Last active
April 24, 2023 12:02
-
-
Save anacampesan/d451168e38d6fd0a6a9fcc32e98a5038 to your computer and use it in GitHub Desktop.
GIF Frame Disposal Correction Algorithm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function explodeGif(gifUrl) { | |
return gifler(gifUrl)._animatorPromise.then(function(gif) { | |
let current = createTempCanvas(gif.width, gif.height, 'current'); | |
let currentCtx = current.getContext('2d'); | |
let temp = createTempCanvas(gif.width, gif.height, 'temp'); | |
let tempCtx = temp.getContext('2d'); | |
gif._animationLength = 0; | |
for (let i = 0; i < gif._frames.length; i++) { | |
let cFrame = gif._frames[i]; // current frame | |
gif._animationLength += cFrame.delay; | |
switch (cFrame.disposal) { // how to recover AFTER drawing the frame | |
case 2: // dispose to background (fill frame rect with transparency) | |
tempCtx.putImageData(new ImageData(cFrame.pixels, gif.width, gif.height), 0, 0); | |
currentCtx.drawImage(temp, cFrame.x, cFrame.y, cFrame.width, cFrame.height, cFrame.x, cFrame.y, cFrame.width, cFrame.height); | |
gif._frames[i].data = currentCtx.getImageData(0, 0, gif.width, gif.height); | |
currentCtx.clearRect(cFrame.x, cFrame.y, cFrame.width, cFrame.height); | |
break; | |
case 3: // dispose to previous (restore frame rect) | |
tempCtx.putImageData(new ImageData(cFrame.pixels, gif.width, gif.height), 0, 0); | |
let prev = currentCtx.getImageData(cFrame.x, cFrame.y, cFrame.width, cFrame.height); | |
currentCtx.drawImage(temp, cFrame.x, cFrame.y, cFrame.width, cFrame.height, cFrame.x, cFrame.y, cFrame.width, cFrame.height); | |
gif._frames[i].data = currentCtx.getImageData(0, 0, gif.width, gif.height); | |
currentCtx.putImageData(prev, cFrame.x, cFrame.y); | |
break; | |
default: // do not dispose (none or unspecified) | |
tempCtx.putImageData(new ImageData(cFrame.pixels, gif.width, gif.height), 0, 0); | |
currentCtx.drawImage(temp, cFrame.x, cFrame.y, cFrame.width, cFrame.height, cFrame.x, cFrame.y, cFrame.width, cFrame.height); | |
gif._frames[i].data = currentCtx.getImageData(0, 0, gif.width, gif.height); | |
break; | |
} | |
} | |
return gif; | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This snipped explodes a GIF (splits into frames) and prepares it to be rendered on a canvas element, which includes fixing the frame disposal. The lib Gifler or any other of your choice is required.
http://themadcreator.github.io/gifler/assets/gifler.js