Imagick vs GD

Jacek Barecki

Introduction

If you want to create a thumbnail, apply a filter to an image or transform it in any other way, you will have to employ an image processing library in your PHP application. It means that you will probably choose GD or ImageMagick. But which one supports a wider range of image formats? Maybe one of them is slower than the other? What other criteria should be taken under consideration when choosing the right library? Read the article to find out!

Availability

Both GD and ImageMagick are available in PHP on the condition that they were installed and configured along with PHP itself. The GD library is included by default since PHP 4.3 so you will probably be able to use it in your project in most server environments. On the other hand, ImageMagick may not always be available and some of the hosting companies don't include it in their offer.

You can run a few lines of code to check the availability of both libraries. The ImageMagick queryFormats() and GD gd_info() functions also list the image formats supported by each of the libraries:

if(extension_loaded('gd')) {
    print_r(gd_info());
}
else {
    echo 'GD is not available.';
}

if(extension_loaded('imagick')) {
    $imagick = new Imagick();
    print_r($imagick->queryFormats());
}
else {
    echo 'ImageMagick is not available.';
}

Supported file types

The list of supported image formats that will be printed out after executing the code is the first sign that the ImageMagick library offers much more functionality than the other one. GD only supports JPG, PNG, GIF, WBMP, WebP, XBM and XPM files, which is not much comparing to over a hundred file types handled by the ImageMagick library.

You may think that you will probably never use all of these uncommon filetypes supported by ImageMagick but this may not be true. In one of my projects I had to switch from GD to ImageMagick just because the first one doesn't support TIFF files.

Functionality

Both GD and ImageMagick offer some basic functionality such as:
- resizing and cropping images,
- creating images that are composed of custom shapes, text and other image files,
- applying image filters (changing the brightness, contrast, colorizing etc.).

If you want to process images in a more advanced way, check all the features of the ImageMagick library. As shown at the ImageMagic example pages – the first one and the second – you can transform the image, decorate it or distort it in countless ways.

The PHP ImageMagick class itself offers 331 methods which is quite an impressive number (no, I didn't count them manually, I used the ReflectionClass ;)). On one hand it shows great reach of the ImageMagick library, while on the other it makes it difficult to find and implement the proper method for a specific use case.

Performance

To tell the truth, if you just want to create a set of thumbnails or apply a simple transformation to an image, you shouldn't care about comparing the performance of each of the image processing libraries.

In a series of tests that I ran on a typical server configuration, creating a thumbnail from a digital camera 3MB JPG image took around 0,6s using ImageMagick and aroung 0,5s using GD. So the whole process doesn't take much time no matter which library is used. And after browsing the web and looking for speed tests of both libraries you will quickly notice that none of them stands out in terms of performance. Sometimes the GD library is the one that works faster, sometimes it is ImageMagick – it simply depends on the use case. Don't take this criterion as a crucial one when deciding whether to use GD or ImageMagick.

Coding style

If you compare the code responsible for the same image transformation written using the GD and the ImageMagick library, you will quickly notice that there are several differences. The GD library is available through a set of functions like getimagesize() or imagecreatetruecolor() so the whole image processing script needs to be written in a procedural style. Let's see an example of creating a JPG image thumbnail:

$src_img = imagecreatefromjpeg('source.jpg');
if(!$src_img) {
    die('Error when reading the source image.');
}
$thumbnail = imagecreatetruecolor(800, 800);
if(!$thumbnail) {
    die('Error when creating the destination image.');
}
$result = imagecopyresampled($thumbnail, $src_img, 0, 0, 0, 0, 800, 800, 1600, 1600);
if(!$result) {
    die('Error when generating the thumbnail.');
}
$result = imagejpeg($thumbnail, 'destination.jpg');
if(!$result) {
    die('Error when saving the thumbnail.');
}
$result = imagedestroy($thumbnail);
if(!$result) {
    die('Error when destroying the image.');
}

As the exceptions aren't thrown in case of an error, all the error handling has to be implemented by checking the result of each GD function. You also have to deal with monstrous functions that have ten arguments, like imagecopyresampled() or imagecopyresized(). I'm convinced that such a number of arguments is not an example of a good coding practice.

Another thing that may not be very convenient is the fact that the functions responsible for reading and saving an image are different depending on the image type. So if you want your thumbnail generator script to handle different file types, you need to add a code like:

switch($image_type) {
    case 'gif' :
        $src_img = imagecreatefromgif($path);
        break;
    case 'png' :
        $src_img = imagecreatefrompng($path);
        break;
    case 'jpg' :
    case 'jpeg' :
        $src_img = imagecreatefromjpeg($path);
        break;
    default:
        return false;
        break;
}

//continue with creating the thumbnail

Then, you will have to execute different functions depending on the image type to save the target image in the proper format. As you can see, the GD code gets complicated fast.

Just look at the ImageMagick code responsible for the same operation and you will notice the difference:

try {
    $imagick = new Imagick();
    $imagick->readImage('source.jpg');
    $imagick->thumbnailImage(800, 800);
    $imagick->writeImage('destination.jpg');
}
catch(Exception $e) {
    die('Error when creating a thumbnail: ' . $e->getMessage());
}

The ImageMagick library is accessible through the Imagick class. Thus, we can benefit from all the object-oriented programming paradigm advantages. The simplest example is the way of handling the errors. When using the ImageMagick library you can just wrap all the code in a try-catch block and your app can be executed safely.

As you can see above, the ImageMagick script responsible for creating a thumbnail doesn't contain any code related to the type of the source image. The same code may be used to process JPG images as well as PNG or TIF files. And if you need to convert the source image to another type, just add one line of code before executing the writeImage() method:

$image->setImageFormat('PNG');

Isn't it just more clear? In my opinion, processing images using the GD library functions is not as handy as with ImageMagick. Of course, there are various wrappers available for GD that make it object oriented, but at that point it starts to feel like patching a patch.

Popularity

As the GD library is included by default in all new PHP versions, you will probably see this library in various projects more often than ImageMagick. When I needed to include in my CakePHP project a component responsible for handling image uploads and thumbnail generation, I quickly found one that suited my needs, based on GD. You may sometimes find some well written modules that let you choose between the two image processing libraries – like the Kohana framework image library, but I'm afraid they are not so frequent.

Alternatives

When deciding how to handle the image processing in your application, you don't need to stick with one PHP library or another. There are other solutions worth considering:

1. Use an image processing script that works outside the PHP application.
In one of my apps I had to create a web page allowing a visitor to transform an image online, just in the browser window. I decided to use the Caman.js JavaScript image processing library which did the job very well. The library may also be employed as a background script embedded within the node.js platform which has been steadily gaining popularity.

2. Employ a cloud-based image processing platform.
A cloud based solution can do the job for you – after sending the source file you can fetch different size thumbnails or images transformed by various filters. You don't need to write too much code and you're not limited by your server capabilities. Just open Google to find some companies that offer such services.

3. Check the functionalities of the components that you're already using.
You may be suprised to find that you can transform your images by employing a service already connected to your application. For example, the Dropbox API offers the thumbnails method that allows you to fetch a JPG or PNG image in one of five available dimensions. Check your libraries' and APIs' documentation and maybe you will find out that they can do the things you need.

Summary

As you can see, each of the image processing libraries has its pros and cons. The GD library is widely available so it will probably work everywhere. As it's popular, you will easily find a lot of examples and components using this library. Getting some help may also be easier as more people may be familiar with the GD library than with ImageMagick.

ImageMagick supports more file types and can transform the images in a lot more ways than the GD library. It also allows you to write code of a higher clarity and quality.

Finally, there are alternatives such as cloud image processing services which might eliminate the need for either of these completely. I hope this article helps you in your choice.

If you have any questions or comments regarding the article, feel free to post a comment below or contact me through Google+.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Dominique

    One of the cool feature of Imagick is the overlay feature, in a way similar to Photoshop you can overlay picture and set them blending options, It allow to create tools like a quoting tools / visualisation tools for house builders, you can then set texture mixed with color, and/or window type/color without having to design all of the case possible.

  • Ian

    Great article and just what I was looking for. I followed along with your examples and found I didn’t need to use: $image->setImageFormat('PNG');

  • Radek

    Check out this great library for handling images in PHP https://github.com/avalanche123/Imagine
    Polska pozdrawia ;)

  • William

    Gdv is OK for simpler smaller images, but when dealing with 5mb JPEG files image magick is by far the better choice.

    If you decide to use image magick then you should try graphics magick. Drop on replacement, much faster and uses less memory.

  • Jurian Sluiman

    For small images, gd and Imagick may perform similar. In our test suite however, larger images are processed faster with Imagick. You also have to measure the memory consumption of both libraries, which you didn’t include in this post. In our experience, Imagick can process images more efficiently as well in terms of memory required.

    Another thing I am pointing out in favour of Imagick: the image quality. As there are lots of configuration options, you can tune the resizing methods to your needs. This allows you to resize images in almost Photoshop quality. This is nearly impossible with gd.

    Considering all, I just cannot understand people are using gd these days. Imagick isn’t that much of a requirement these days and it outperforms gd in many ways. If you’re really concerned about speed, check out Gmagick, as mentioned above as well. It’s an Imagick fork with better memory consumption and better image quality. However, it’s not that easy to install Gmagick in comparison with Imagick.

  • Dave

    My understanding is that it is generally recommended to make shell calls to ImageMagick, rather than using the Imagick PHP extension. To quote from http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=22397#p93238

    Imagick is not supported well if at all any more and was not created by the ImageMagick team. So I am not sure what to tell you at this point other than to just use PHP exec() for everything. You are not gaining much if anything from Imagick and it does not support many of the newer Imagemagick features.

    BTW, why is Sitepoint now requiring Disqus for making comments? I don’t think I’ve ever read anything good about Disqus.