Help with animated GIF compression

IMagick is a native PHP extension to create and modify images using the ImageMagick API. ImageMagick Studio LLC did not write nor does it maintain the IMagick extension, however, IMagick users are welcome to discuss the extension here.
Locked
pjclas
Posts: 2
Joined: 2014-09-11T11:52:14-07:00
Authentication code: 6789

Help with animated GIF compression

Post by pjclas »

I have an animated gif that is 150k in size. I read in this gif, coalesce it so I can add content, and then I optimize/merge/reconstruct the layers and write it back out. I noticed that the result file size was much larger than I expected so I tried not adding any content after I coalesced it and it still is bigger than the original file. Here is the code I'm running:

Code: Select all

            $image = new Imagick("test.gif");
            $image = $image->coalesceImages();

            // now merge the layers
            $image->mergeImageLayers(Imagick::LAYERMETHOD_OPTIMIZE);

            // I also tried using the following
            // $image->optimizeImageLayers();
            // $image = $image->deconstructImages();

           $image->writeImages("test2.gif", true);
The result is that test2.gif is around 200k, but test.gif is 150k. I've tried various optimizations, but I can't seem to get the file size to change at all so I know I'm just doing something wrong. Do optimizations needs to be applied to each frame in the animated image individually at some point? I just want to figure out how to get the new file to be approximately the same size (or even smaller) than the original file, but I'm really struggling.

I also can't figure out the difference between mergeImageLayers, optimizeImageLayers, and dconstructImages... Any help would be very much appreciated. If anyone wants to try doing this, the image I'm using is Image

pjclas
Posts: 2
Joined: 2014-09-11T11:52:14-07:00
Authentication code: 6789

Re: Help with animated GIF compression

Post by pjclas »

For anyone interested I was able to get the filesize closer to the original by forcing all frames to use a global color map (instead of a color map for each frame). It's not obvious how to do this, but what you need to do is append the frames together into one image and then use that image to remap every frame (at least that's what I did).

Code: Select all

            // make all the frames the same size
            $image = $image->coalesceImages();
            // generate a colormap from combining all the frames
            $colormap = $image->appendImages(true);

            $image->remapImage($colormap, 0);
            while($image->hasNextImage()) {
                $image->nextImage();

                // get rid of the local color tables for each frame and use a single global color table
                $image->remapImage($colormap, 0);
            }

            // now compare the layers
            $image = $image->compareImageLayers(Imagick::LAYERMETHOD_COMPAREANY);

            // write the image
            $image->writeImages("test2.gif", true);
I'm still at about 170k filesize though. I tried running it through the command line convert tool with -layer OptimizeTransparency and that reduced it even further to 165k, but I can't seem to replicate that command in the IMagick apis. Any ideas?

Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Help with animated GIF compression

Post by Bonzo »

Thanks for coming back and posting your answer.

Imagick only supports some of the options available in Imagemagick and the one you want may not be one of them.

Locked