Seriously.js icon indicating copy to clipboard operation
Seriously.js copied to clipboard

Callback/event when the Chromakey effect has been applied to an image

Open polomoshnov opened this issue 7 years ago • 4 comments

Right after seriously.go() I do target.toDataURL('image/png') and get an empty image. But if I setTimeout(function () { target.toDataURL('image/png') }, 1000) the image is not empty and has the Chromakey effect applied successfully. (For the source I use an image not a video.) I think the effect is being applied asynchronously and that's why that happens.

polomoshnov avatar Dec 09 '17 07:12 polomoshnov

Are you preloading the image?

It should be drawn on the next frame. For that, you can do requestAnimationFrame(yourCallback)

positlabs avatar Dec 09 '17 17:12 positlabs

While a lot of threads on different websites say otherwise, toDataURL() is now asynchronous (at least on Chrome) : https://bugs.chromium.org/p/chromium/issues/detail?id=514206

You can fix this using a promise/callback instead of a timeout. For example :

    return new Promise(resolve => {
        const img = new Image();
        ...<snip>...

        img.onload = function() {
            resolve(img);
        };

        img.src = canvas.toDataURL("image/png");
    });

spoji avatar Feb 06 '19 13:02 spoji

I am having the exact same issue. The target canvas worked perfectly. I wrapped the method in an onload event as specified above but I still get a transparent image. Hoping you can help.Thanks in advance.

 var seriously = new Seriously();
            var source = seriously.source(media);
            var target = seriously.target(canvas);
            chromaEffect = seriously.effect("chroma");
            chromaEffect.screen = [0 / 255, 117 / 255, 49 / 255, 0];
            chromaEffect.weight = 1;
            chromaEffect.balance = 1;
            chromaEffect.clipBlack = 0;
            chromaEffect.clipWhite = 1;
            chromaEffect.source = source;
            target.source = chromaEffect;
            seriously.go();

var finalImg = new Image();

                finalImg.onload = function () {
                    $media.attr("src", finalImg.src);
                }

                finalImg.src = canvas.toDataURL("image/png");

juliandormon avatar Dec 22 '19 00:12 juliandormon

I figured it out. I had to put my final functions within the go(callback);

var seriously = new Seriously();
            var source = seriously.source(media);
            var target = seriously.target(canvas);
            chromaEffect = seriously.effect("chroma");
            chromaEffect.screen = [0 / 255, 117 / 255, 49 / 255, 0];
            chromaEffect.weight = 1;
            chromaEffect.balance = 1;
            chromaEffect.clipBlack = 0;
            chromaEffect.clipWhite = 1;
            chromaEffect.source = source;
            target.source = chromaEffect;
            seriously.go(function () { 

var finalImg = new Image();

                finalImg.onload = function () {
                    $media.attr("src", finalImg.src);
                }

                finalImg.src = canvas.toDataURL("image/png");

});

juliandormon avatar Dec 22 '19 17:12 juliandormon