When resizing and cropping images, many popular PHP packages break the GIF animation and save it as a static image. However, it is possible to resize and crop image while keeping the animation intact. In PHP, this can be achieved by using the ImageMagick extension.
Installing ImageMagick
On most servers, ImageMagick is not installed by default. However, you can install it by running a couple of Linux commands. On CentOS operating systems, use the yum package manager.
First, install the required dependencies:
yum install -y gcc php-devel php-pear
Install ImageMagick:
yum install -y ImageMagick ImageMagick-devel
Install PHP extension:
pecl install imagick
Restart Apache web server:
service httpd restart
On Ubuntu server, do the same process. First, install the required dependencies:
sudo apt-get install php5 php5-common gcc
Install ImageMagick:
sudo apt-get install imagemagick
Install PHP extension:
sudo apt-get install php5-imagick
Restart Apache:
service apache2 reload
Resizing GIF Animations
To resize a GIF animation, we will use resizeImage function. However, since each animation consists of multiple images (frames), we need to loop through all of them, resize them one by one and merge them into one image again. In PHP, it is done like this:
// Create new Imagick class
$image_folder = 'images/';
$image_path = 'images/animation.gif';
$imagick = new Imagick($image_path); // $image_path is the path to the image location
// Split gif animation into image
$imagick = $imagick->coalesceImages();
// Crop images one by one
do {
// First parameter is resized image width and second is resized image height
// If one of the params is set to zero, image will keep the aspect ratio
$imagick->resizeImage(580, 0, Imagick::FILTER_BOX, 1);
} while ($imagick->nextImage());
// Reassemble the animation
$imagick = $imagick->deconstructImages();
// Save gif animation
// This would overwrite the original image
$imagick->writeImages($image_path, true);
Cropping GIF Animations
For cropping an GIF animation, the same principle is used as for resizing them. The only difference is that cropImage function is used instead of resizeImage function. Here is the example:
// Create new Imagick class
$image_folder = 'images/';
$image_path = 'images/animation.gif';
$imagick = new Imagick($image_path); // $image_path is the path to the image location
// Split gif animation into image
$imagick = $imagick->coalesceImages();
// Crop images one by one
do {
// First two params are width and height of the crop and third and fourth are the starting points of the crop
// E.g. if the last two params are 0,0, that means that cropping will start from the top left corner
$imagick->cropImage(400, 200, 0, 0);
// After the crop, there is some blank space remaining on the image since the image canvas has remained the same size
// This function resizes the image canvas and thus eliminates the blank space
$imagick->setImagePage(400, 200, 0, 0);
} while ($imagick->nextImage());
// Reassemble the animation
$imagick = $imagick->deconstructImages();
// Save gif animation
// This would overwrite the original image
$imagick->writeImages($image_path, true);
Notes
Manipulating GIF animations require a lot of hardware resources and takes a significant amount of time. Have that in mind while building your web application.