I search for a long time how to extract frames from an animated GIF with PHP... unfortunaly I just found how to get their duration...
I really need to extract the GIF frames and their duration to apply some resize, rotate, etc, on each and then to regenerate the GIF with edited frames !
I don't want to use any software, external library (like ImageMagick), just PHP: in fact I need to allow my class http://phpimageworkshop.com/ to work with animated GIF.
If you have any idea, I'm listening you ^^ !
I spent my day creating a class based on this one to achieve what I wanted using only PHP!
You can find it here: https://github.com/Sybio/GifFrameExtractor
Thanks for your answers!
Well, I don't really recommend doing it this way, but here's an option. Animated gifs are actually just a number of gifs concatenated together by a separator, "\x00\x21\xF9\x04". Knowing that, you simply pull the image into PHP as a string, run an explode, and loop through the array running your transformation. The code could look something like this.
$image_string = file_get_contents($image_path);
$images = explode("\x00\x21\xF9\x04", $image_string);
foreach( $images as $image ) {
// apply transformation
}
$new_gif = implode("\x00\x21\xF9\x04", $images);
I'm not 100% sure of the specifics of re-concatenating, the image, but here's the wikipedia page regarding the file format of animated GIFs.
I am the author of https://github.com/stil/gif-endec library, which is significantly faster (about 2.5 times) at decoding GIFs than Sybio/GifFrameExtractor
library from accepted answer. It has also less memory usage, because it allows you to process one frame after another at decode time, without loading everything to memory at once.
Small code example:
<?php
require __DIR__ . '/../vendor/autoload.php';
use GIFEndec\Events\FrameDecodedEvent;
use GIFEndec\IO\FileStream;
use GIFEndec\Decoder;
/**
* Open GIF as FileStream
*/
$gifStream = new FileStream("path/to/animation.gif");
/**
* Create Decoder instance from MemoryStream
*/
$gifDecoder = new Decoder($gifStream);
/**
* Run decoder. Pass callback function to process decoded Frames when they're ready.
*/
$gifDecoder->decode(function (FrameDecodedEvent $event) {
/**
* Write frame images to directory
*/
$event->decodedFrame->getStream()->copyContentsToFile(
__DIR__ . "/frames/frame{$event->frameIndex}.gif"
);
});
I don't want to use any software, external library (like ImageMagick)
Well, good luck with that, because 90% of the functionality the Zend Engine exports to the PHP runtime comes from libraries.
If you have any idea, I'm listening you ^^ !
Parse the binary data in the GIF format. You could use unpack(), among other things.