preloading images into browser cache - javascript

I'm trying to make an image gallery that will show lots of art. Therefore the website will have lots of images. I noticed that when I viewed my code on another computer the images would take time to load. While on my computer they would display straight away and I guessing this is due to them already being cached.
So I did some looking around to see if I could prevent this and I found lots of people mentioning preloading images. However, I couldn't really find a solution that fits my desire or a explanation I could understand(I hate using code I don't understand). So I tried to have a go myself and it didn't work out, but I felt the logic I what I writing was right but needs tweaking I'm going to write my code below and any advice on what need to do next would be greatly appreciated.
Preloading images code:
var allImages = $(img).attr('src'); //select every image
var preloadImages = [];
//add images to empty array
for(var i = 0; i < allImages.length; i++ ) {
preloadImages.push(allImages[i]);
}
//then preload images
for(var i = 0; i < preloadImages.length; i++ ) {
new Image().src = preloadImages[i];
}
So that is the code I wrote to preload images on my page. Let me know where I'm going wrong. I'm really not sure how I go about selecting all images on my website and loading them into an array I can then cycle over?
Thanks for the responses I guess I didn't explain my problem that well. A lot of the solutions to preloading images seem to be manually typing in every image src into and array. What I was looking for was a way to select every image I have and then put them into an array without actually typing them in. Is that possible? My reason for that is when I keep adding more and more images it would be great if the preloading could just take care of itself.

Related

How to improve OpenCV background drop from two images

I am using OpenCV with NodeJS (opencv4nodejs) and am attempting to replace background from webcam pics (one with and one without head in the frame).
My code works but the quality of the mask is useless presumably because I need to apply better filters but I am not sure what.
Here's my simple code
const bgSubtractor = new cv.BackgroundSubtractorMOG2()
const back = cv.imread('/app/src/services/back.jpg').bgrToGray()
const face = cv.imread('/app/src/services/face.jpg').bgrToGray()
bgSubtractor.apply(back)
return bgSubtractor.apply(face)
I've gray scaled them but that's about it. I'm not attaching particular images as I want to see if I can make a generic model but the intention is to replace the background from someone taking a headshot with their cam then asked to drop out for the background (which could vary) shot. I am not sure it's possible to obtain a decent quality with just two images though.
Perhaps a different would be better? I assume that if I could properly align the images to account for minor shifts between stills and subtract but perhaps that's what the cv.BackgroundSubtractorMOG2 does? I've worked from a few examples that use movies but the results didn't pan out well.
As #rayryeng pointed out, MOG2 Bg Subtractor needs to be trained with several background samples in order to be able to understand what a background actually is.
Try in this way:
take several background images (pretty obvious :) )
feed with them the MOG object with a
learning rate > 0
apply trained MOG to your frame with learning rate
= 0 to retrieve foreground objects
Very useful link that explains everything

How to stop an animated gif from looping

I have an animated gif in an img tag that I start by rewriting the src attribute. The gif was created, though, to loop and I only want it to play once. Is there a way, with Javascript or jQuery, to stop an animated gif from playing more than once?
I was having the same problem with an animated gif. The solution is rather simple.
Open the Animated gif in Photoshop.
Go to the Window tab and select timeline(if the timeline is not already open).
At the bottom of the timeline panel, you will find an option, which says "Forever".
Change that to "Once".
Go to File> Export> Export for Web and save it as a gif.
That should do it.
can you find out how long the gif takes to loop once?
if so then you can stop the image like this:
pseudocode:
wait until the end of the image (when it is about to loop)
create a canvas element that has a static version of the gif as currently displayed drawn on it
hide gif
display canvas element in a way that makes it look like the gif froze
javascript:
var c = $("canvas")[0];
var w = c.width;
var h = c.height;
var img = $("img")[0];
setTimeout(function () {
c.getContext('2d').drawImage(img, 0, 0, w, h);
$(img).hide();
$(c).show();
},10000);
jsfiddle
edit:
I forgot to add reference to the original answer that I took this from, sorry
Stopping GIF Animation Programmatically
that one doesn't address the time factor you need for only one loop
Also, it has been mentioned that this approach is problamatic in certain cases (It actually didn't work when I try it in firefox right now...). so here are a few alternatives:
mentioned by Mark: edit the gif itself to avoid looping. this is the best option if you can.
but I've run into cases where it was not an option (like automated generation of images by a third party)
instead of rendering the static image with canvas, keep a static image version and switch to stop looping . this probablyhas most of the problems as the canvas thing
Based on this answer, it's kinda expensive, but it works. Let's say a single loop takes 2 seconds. At a setTimeout after 2 seconds kick in a setInterval, that would reset image source every millisecond:
setTimeout(function() {
setInterval(function() {
$('#img1').attr('src',$('#img1').attr('src'))
},1)
}, 2000)
again, probably just a proof of concept, but here's demo: http://jsfiddle.net/MEaWP/2/
Actually it is possible to make a gif to stop after just one iteration or any specific number of iterations, see an example below (if it is not already stopped), or in jsfiddle.
To do that the gif must be created with number of iterations specified. This could be done using Screen to Gif, it allows to open a gif or a bunch of images and edit it frame by frame.
This solution also allows you to reset the animation by imgElem.src = imgElem.src; but this does not work in MS IE/Edge.
Jurijs Kovzels's answer works in some condition but not in all.
This is browser-dependent.
It works well with Firefox. But In Google Chrome and Safari, it does not work if the gif is on the same server. The example he provided works because the gif is on the external server.
To restart gifs stored on the internal server, using Google Chrome and Safari, you need extra steps to make it work.
const img = document.getElementById("gif");
img.style = "display: none;";
img.style = "display: block;";
setTimeout(() => {
img.src = img.src;
}, 0);
This is inspired by this answer.
Not sure if this is the best way to respond to everyone and have it appear after all the previous answers and comments, but it seems to work.
I don't have much control over the gif. People post whatever gif they want as the "thankyou.gif in their account directory and then the ThankYou code runs whatever they've put there when a comment is submitted to a form they've posted. So some may loop, some may not, some may be short, some may be long. The solution I've come to is to tell people to make them 5 seconds, because that's when I'm going to fade them out, and I don't care if they loop or not.
Thanks for all the ideas.
I know I am pretty late here but..here it is...
I don't know if you would go to this length but let me share a trick.
Open the GIF in Macromedia Flash 8(it has deprecated since then), Export the GIF as Animated GIF. You will have to choose the file location. After that you would receive a dialog box with settings. In that, add the number of times you want the animation to happen. Click OK. Problem solved.

Export Photoshop Groups as separate images

I'm currently working with several different Photoshop files. They all contain up to 10-40 Groups with even more layers. I want to export every group as an "image for web" in a different size than the document size.
Basically this is quite simple and should work like this in pseudo-code:
for i = layerGroups; i > 0; i--;
export layergroup[i] for web with "width=200 and height=120"
I'm experienced in javascript coding, however, I've never coded a Photoshop script yet, so this is where the difficulties begin. Hopefully, I could render out my problem and get some helping hands.
Cheers

Javascript images array preload speed and remove from memory

I have a asp.net MVC application where I display a number of image in a view, the number of these images rang between 100 to 2500 per group. On the view I preload the images for each group, then I select a different group from a dropdownlist, this will refresh the page. First preload works great, however, when I change the group it is very slow. The reference to these images are in a MS SQL database, the list of images for a particular gorup comes throught the controller (C#). Here is the Javascript I am using:
var impath = $("#ImagePath").val();
var im = $("#ImageName").val();
var images = null;
var images = [];
var tochar = $("#lastchar").val();
function preload_images() {
var i;
for (i = tochar; i < sl; i++) {
images[i] = new Image();
var name = impath.toString() + im.toString() + i;
}
}
My question is there is a way to speed up the preload process, and do I need to remove the preloaded images from the memory before loading the next group and how can I delete them, I used images=null, is this is the right way. Thanks in advance.
The best way to handle that many images would be using sprites. With sprites, you load one larger image that contains many, many smaller images. Since loading a single image is lot, lot faster in the browser than loading a lot of small images, your preloading can be a lot faster. In fact, you could literally just preload one image that contained a whole block of your sub-images.
Then, when you want to display one of those images, you display only a clipped portion of the image. There are a number of ways to do that display, but a common way is creating an object of the desired cell size and displaying the larger image as the background with the appropriate offset to line up with the desired part of the larger image.
Here's a useful reference on CSS and sprites: http://css-tricks.com/css-sprites/
You do have to create the appropriate sprites on the server side to use this technique.
In answer to some of your other questions.
No, you can't speed them up any more other than loading fewer images (as suggested above) or reducing the size of each image. The browser will only make N image requests at a time (likely to avoid overloading servers) over the network so the rest will be queued up until one finishes and then the next request will be made, etc...
You can release images from memory by just making sure that you aren't holding a reference to them any more. That way, the browser garbage collector will clean up the Image() objects that you had created. In your code setting images = null or images = [] will accomplish that as long as those Image() objects aren't referenced anywhere else. The images will still remain in the browser's cache and will still essentially be preloaded (they won't have to be loaded over the network if referenced again).

Modifying flipbook jquery to load faster

I am using the Flipbook jquery plugin with a large png image sequence. I emailed the creator of the plugin and asked if there's any way to create some sort of "loader" or allow it to load in chunks and start playing after a certain amount of images are loaded. He responded with the following:
This should be possible and I was thinking of doing this but it wasn't needed at the time.
In the flip book code the shouldStartAnimation function determines if the animation should start by incrementing a counter and checking that counter against the total number of frames. When all the frames have been loaded the timer starts which flips the frames. This code could be changed so the timer starts after half the frames were loaded or something. It could also get really fancy and figure out how long each frame is taking to load and then guess how many frames it needs to let load before it can start playing the sequence so all the frames are loaded by the time it needs them.
Unfortunately I don't have time to make these changes myself, but feel free to modify this code for your needs :)
https://gist.github.com/719686
Unfortunately I don't know enough javascript to get this done, and I don't know exactly how much work this would be for someone who did. I am just hoping someone here might have some more helpful info or advice to help me figure this out (or, obviously, if this is easy enough for someone to just do, that would be amazing).
Add one more option default, the following, make sure to have proper "comas" in right places.
'loadbeforestart': 10, //start animation when 10 frames are loaded
And edit a variable in the following function, replace variable "end" with "loadbeforestart"
function shouldStartAnimation(){
//console.log('pre: '+imageName(i));
preloadCount += step;
if(preloadCount >= loadbeforestart){
setTimeout(flipImage, holdTime);
}
}
This should do the trick, I think*

Categories