jnordberg / gif.js

JavaScript GIF encoding library
http://jnordberg.github.io/gif.js/
MIT License
4.78k stars 668 forks source link

Black screen at the beginning of the creation of the gif. #76

Open YeisonVelez11 opened 7 years ago

YeisonVelez11 commented 7 years ago

When I start my gif I have a black screen. How can I remove it?

                       var gif = new GIF({
                              workers: 2,
                              quality: 10
                        });

                          for (var x = 0; x < frames.length; x++) {
                                res_ctx.putImageData(frames[x],0,0);
                                var image_gif = new Image();
                                image_gif.src = res_c.toDataURL("image/png");
                                image_gif.height=img.height;
                                image_gif.width=img.width;
                                gif.addFrame(image_gif,{delay: 100});
                            }

                            gif.render();
1j01 commented 7 years ago

An Image has to load (even though it's a data URL), which would introduce asynchronous behavior. You should be able to pass in the ImageData objects directly, with no res_c/res_ctx needed. Alternatively you could pass res_ctx, in which case you'd need copy: true in the options since you're changing the content on the canvas after passing it.

YeisonVelez11 commented 7 years ago

@1j01 I have an image for example "img/Myimage.jpg" I would like to convert it to the Uint8ClampedArray format (as shown in the image). http://i.imgur.com/h34rf7f.jpg

For what? I am using a library that after a long process converts the images to this format, but I have others images that I need to convert them on my own to this same format. how can I do it? Excuse my ignorance

                var frames = animator.frames;
                var res_c = document.getElementById("result");
                var res_ctx = res_c.getContext('2d');
                for (var x = 0; x < frames.length; x++) {
                //***frames are ImageData (Uint8ClampedArray)***
                    res_ctx.putImageData(frames[x],0,0);
                    console.log(frames[x])
                    gif.addFrame(res_c,{copy:true,delay: 120});
                }
                // need convert my images in ImageData (Uint8ClampedArray) for add others frames
1j01 commented 7 years ago

I'm not sure I understand the problem. Are you assuming you need to pass the image data in the same way for all frames? You should be able to add frames as Image/<img> objects too, but you do need to wait for them to load.

If you have an array of URLs of images to load, you can use something like this (taken from here and edited):

function waitForImagesLoaded(imageURLs, callback){
    var imageElements = [];
    var remaining = imageURLs.length;
    var onEachImageLoad = function(){
        if (--remaining === 0 && callback) {
            callback(imageElements);
        }
    };

   // first create the images and apply the onload method
   for (var i = 0, len = imageURLs.length; i < len; i++){
      var img = new Image();
      imageElements.push(img);
      img.onload = onEachImageLoad;
      img.src = imageURLs[i];
   }
}

Like so:

var urlsToLoad = ["img/MyImage.jpg"];
waitForImagesLoaded(urlsToLoad, function(images){
    for (var i = 0; i < images.length; i++) {
        gif.addFrame(images[i]);
    }
});
YeisonVelez11 commented 7 years ago

@1j01 Thank you! it worked!

ranbuch commented 6 years ago

I'm having the same problem but my images are base64 strings so pre-loading them isn't helping. h I can clearly see the first images has a valid base64 images with content.

I was using workers: navigator.hardwareConcurrency || 2, witch is 8 in my case.

When using workers: 2 that is the result: h2 When using workers: 1 that is the result: h3 When using workers: 0 doesn't return any value.

ranbuch commented 6 years ago

Although those are a base64 images the img.onload trick works for me as well. s