Perfect implementation of GIF animation thumbnail PHP code

  • 2020-03-31 21:29:11
  • OfStack

The following is an animated GIF from the CS police and bandits game to illustrate the problem: (link: https://www.jb51.net/upload/201101/20110102000751167.gif)

Animated GIF image: old.gif

To make the problem clearer, we first restore each frame of the animation:

Option 1: use the Imagick module in PHP:

 
<?php 
$image = new Imagick('old.gif'); 
$i = 0; 
foreach ($image as $frame) { 
$frame->writeImage('old_' . $i++ . '.gif'); 
} 
?> 

Option 2: use the convert command provided by ImageMagick:
 
shell> convert old.gif old_%d.gif 

The result is the schematic diagram of each frame of GIF animation as shown below:

(link: https://www.jb51.net/upload/201101/20110102000752620.png)

Schematic diagram of each frame of GIF animation

It can be seen clearly that in order to compress the GIF animation, the first frame will be used as the template, and the remaining frames will be accumulated in sequence according to the appropriate offset, and only different pixels will be retained. As a result, the frame sizes will be different, which will cause obstacles for the thumbnail image.

Here's how to use the Imagick module in PHP to perfectly implement GIF animated thumbnails:

 
<?php 
$image = new Imagick('old.gif'); 
$image = $image->coalesceImages(); 
foreach ($image as $frame) { 
$frame->thumbnailImage(50, 50); 
} 
$image = $image->optimizeImageLayers(); 
$image->writeImages('new.gif', true); 
?> 

The key code is (link: http://www.php.net/manual/en/function.imagick-coalesceimages.php) method, it ensures that the frame size is consistent, in manual terms is:

Employees of a set of images while respecting any page offsets and disposal methods. GIF, MIFF, And MNG animation sequences typically start with an image background and each subsequent image varies in size and offset. Returns a new Imagick object where each image in the sequence is the same size As the first and composited with the next image in the sequence.

Note (link: http://www.php.net/manual/en/function.imagick-optimizeimagelayers.php) method at the same time, it content, remove duplicate pixels in handbook terms is:

Compares the each image the GIF disposed the forms of the previous image in the sequence. From this it attempts to select the smallest cropped image to replace the each frame, While preserving the results of the animation.

BTW: if you require more perfect, can be used to further compression (link: http://www.php.net/manual/en/function.imagick-quantizeimages.php) method.

Note: both coalesceimages and optimizeImageLayers return a new Imagick object!

If you're more comfortable with the shell, you can implement GIF thumbnails like this:

 
shell> convert old.gif -coalesce -thumbnail 50x50 -layers optimize new.gif 

The generated new. GIF is as follows:

 

(link: https://www.jb51.net/upload/201101/20110102000755310.gif)

New. GIF

One detail: the convert version will be smaller than the PHP version due to inconsistent API implementations.


Related articles: