-1

So since animated GIFs are a series of GIFs concatenated together with "\x00\x21\xF9\x04", I am able to explode the GIF and implode it to take it apart and build it again. However I can't seem to get GD to create an image from the data.

Is there something I need to append in order to have GD recognize the data?

$im = file_get_contents('test.gif'); //get the data for the file

$imgarray = explode("\x00\x21\xF9\x04", $im); //split up the frames

foreach ($imgarray as $frame) {
    $img[] = imagecreatefromstring($frame); //this is the line that fails
}

$new_gif = implode("\x00\x21\xF9\x04", $img); //this should work but imagecreatefromstring fails


$new_gif = implode("\x00\x21\xF9\x04", $imgarray); (Does work as it just puts the image back together)
fmw42
  • 46,825
  • 10
  • 62
  • 80

2 Answers2

2

A GIF does not contain just separate images appended after each other. A frame in a GIF may change just a part of the image - it does not have to cover the whole frame. It can also contain a local palette, but otherwise it relies on the global palette of the image - which is stored for the file itself and not just the frame.

I.e. - you can't just explode the file and decode each segment separately and except to get useful images from GD.

You'll at least have to add the gif header to each set of image data, but I strongly recommend using the PHP ImageMagick interface instead if possible - it has far better support for iterating through frames in an image.

Another option is using a pure PHP implementation that does what you want, such as GifFrameExtractor.

The relevant code is located at line 137 of the source file:

$img = imagecreatefromstring(
    $this->fileHeader["gifheader"] .
    $this->frameSources[$i]["graphicsextension"] .
    $this->frameSources[$i]["imagedata"] .
    chr(0x3b)
);

As you can see, there is far more data necessary (the header, the extension (87a vs 89) and a terminating character) to make it valid GIF data.

MatsLindh
  • 49,529
  • 4
  • 53
  • 84
  • Thanks this is great info. I was using ImageMagick but it was unbearably slow for the scale I am trying to create (images on the fly). You gave me a lot to think about though. –  Jul 25 '19 at 17:45
  • I'd consider looking into something a bit more optimized than GIF for stuff on the fly - there's many decent near-real-time conversion tools for streaming mp4 etc. (and the bandwidth necessary for GIF will be through the roof) – MatsLindh Jul 25 '19 at 19:41
0

In Imagemagick, this is pretty trivial. You can coalesce the image to fill out any frames that have been optimized, then do your processing, then optimize it again.

Input:

enter image description here

convert bunny.gif -coalesce -resize 50% -layers optimize bunny_small.gif


enter image description here

fmw42
  • 46,825
  • 10
  • 62
  • 80