Create Dynamic Images with ImageMagick
Digital images and graphics can make web sites more visually appealing and intuitive to navigate. They can serve as extremely concise ways to illustrate ideas, allowing us to replace the proverbial “thousand words” with a single picture. But so many of the images on the Web suffer from a major weakness: they’re static. The size, resolution, colors, and other properties that they had when they were first loaded onto the web server do not change.
If your site displays static images, those images cannot be changed in response to the user’s interaction with your site, regardless of how valuable that ability might be for your site’s users. Even worse, only you are able to change them, and it’s a manual process that requires you first to modify the images on your desktop computer, then upload them again to your web server.
Imagine the possibilities that would open up if you could make your web site change the appearance of the images it displayed, based upon input from you, or any other authorized site visitor. We’re not just talking about changing an image’s location on the page, but such properties as its size, resolution, borders, contrast, and dithering. Imagine being able to automatically rotate an image, flip it around, add tinting, or combine multiple graphics into one.
You could enlarge a street map without having to store separate versions of that image on your server (one for every possible level of resolution that a user might request); you could alter the colors of an image for any site visitors who indicate that they have particular forms of color blindness; you could allow people to rotate aerial shots at will, or allow shoppers to change the tinting of art prints prior to purchase. You could even create an online image editor.
Digital Image Magic
The key component for making dynamic images a reality on your site is an image manipulation program that’s controlled by the code that generates your web pages. Even though this article uses PHP as the scripting language, other languages — such as Perl and Ruby — can be used just as easily, provided that the image manipulation program that you’re considering has an application programming interface (API) for the chosen language.
I’ve chosen to use ImageMagick in this article for several reasons:
- it is more commonly supported by web hosting services than any other package
- it is free
- it runs on Windows and Linux platforms
- it boasts two decades of continual enhancements and bug fixing
- it is robust and powerful, offering extensive capabilities
Instructions for downloading and installing ImageMagick can be found on the ImageMagick web site.
ImageMagick offers a wealth of powerful features, but all of them must be run from the command line. To gain access to that functionality from your PHP-powered web site, you’ll need to use an API (in the form of a PHP extension), such as MagickWand or imagick. The examples that follow utilize the MagickWand API, so you’ll need it installed on your web server (as well as ImageMagick) to play along.
Commands Other than “Abracadabra”
Regardless of the type of operation you want to perform on an image, first of all, you need to load that image into computer memory, and assign it to a MagickWand resource. The following PHP script loads a sample image file from the current directory, then displays it in the web browser:
<?php // script_1.php
$resource = NewMagickWand();
MagickReadImage( $resource, ‘image_1.jpg’ );
header( ‘Content-Type: image/jpeg’ );
MagickEchoImageBlob( $resource );
?>
Figure 1: The original image, displayed in the browser
Once you have created that MagickWand resource and loaded an image, you can find out information about the image, such as its dimensions:
<?php // script_2.php
$resource = NewMagickWand();
MagickReadImage( $resource, ‘image_1.jpg’ );
$width = MagickGetImageWidth( $resource );
$height = MagickGetImageHeight( $resource );
echo “Image size, in pixels, is: width $width x height $height”;
?>
Figure 2: Determining an image’s dimensions
Perhaps you’d like to limit the physical dimensions of any image uploaded by site visitors? This can be done either by trimming all points of the image that lie outside of a rectangular sub-image, or by scaling the original image to fit inside specified bounding dimensions.
In the first case, let’s say that your application needs to discard everything outside of the upper left 200×50-pixel portion of the image. The upper left corner is considered the offset (0,0). The following script will crop the sample image before displaying it:
<?php // script_3.php
$resource = NewMagickWand();
MagickReadImage( $resource, ‘image_1.jpg’ );
MagickCropImage( $resource, 200, 50, 0, 0 );
header( ‘Content-Type: image/jpeg’ );
MagickEchoImageBlob( $resource );
?>
Figure 3: A cropped image
In the second case, let’s say that your application calls for the preservation of the image as a whole, but needs to scale the image down to a smaller size (such as a maximum of 200×200 pixels). The following script will resize the image:
<?php // script_4.php
$resource = NewMagickWand();
MagickReadImage( $resource, ‘image_1.jpg’ );
$resource = MagickTransformImage( $resource, ‘0x0’, ‘200×200’ );
header( ‘Content-Type: image/jpeg’ );
MagickEchoImageBlob( $resource );
?>
Figure 4: A scaled image
The image shown above illustrates how the MagickTransformImage
function automatically preserves the image’s aspect ratio when scaling.
Also note that MagickTransformImage
returns the transformed image as a new resource, which must be assigned to a variable in order to be preserved. In contrast, the previous function that we considered — MagickCropImage
— acted upon the resource variable that was passed to it; it returns a boolean value (TRUE or FALSE). When writing your own MagickWand code, be sure to confirm the return type of each function, since any incorrect assumptions can result in considerable time spent debugging.
Perhaps an image has a border of 20 pixels on its left and right sides that you wish to eliminate, though you don’t want to remove any pixels from the top or bottom of the image. The following script will do just that:
<?php // script_5.php
$resource = NewMagickWand();
MagickReadImage( $resource, ‘image_1.jpg’ );
MagickShaveImage( $resource, 20, 0 );
header( ‘Content-Type: image/jpeg’ );
MagickEchoImageBlob( $resource );
?>
Figure 5: A trimmed image
Next, let’s suppose that you have an image in PNG format, and you would like to reformat it as a JPEG image. Here’s the script that performs the conversion:
<?php // script_6.php
$resource = NewMagickWand();
MagickReadImage( $resource, ‘image_1.png’ );
MagickSetImageFormat( $resource, ‘JPEG’ );
header( ‘Content-Type: image/jpeg’ );
MagickEchoImageBlob( $resource );
?>
Figure 6: A JPEG image converted from PNG format
Images can also be rotated! Perhaps you’d like to rotate the above image 45 degrees in a clockwise direction? Easy!
<?php // script_7.php
$resource = NewMagickWand();
MagickReadImage( $resource, ‘image_1.jpg’ );
MagickRotateImage( $resource, null, 45 );
header( ‘Content-Type: image/jpeg’ );
MagickEchoImageBlob( $resource );
?>
Figure 7: A rotated image
In the above script, we didn’t specify a color to be used for any areas that were newly exposed as a result of the rotation. But we can certainly do that:
<?php // script_8.php
$resource = NewMagickWand();
MagickReadImage( $resource, ‘image_1.jpg’ );
MagickRotateImage( $resource, NewPixelWand( ‘blue’ ), 45 );
header( ‘Content-Type: image/jpeg’ );
MagickEchoImageBlob( $resource );
?>
Figure 8: Image rotated, with blue background
Pulling the Rabbit from the Hat
After you’ve made all the desired changes to an image — or your PHP script has allowed your site visitor to do the same — you can display the finished image in your visitor’s web browser (as we’ve done above), or you can save the new image back to disk. Let’s modify our previous sample script to save the image to disk:
<?php // script_9.php
set_time_limit( 60 * 5 );
$resource = NewMagickWand();
MagickReadImage( $resource, ‘image_1.jpg’ );
MagickRotateImage( $resource, NewPixelWand( ‘blue’ ), 45 );
MagickWriteImage( $resource, ‘new_image.jpg’ );
?>
You will notice an additional change here: set_time_limit sets the script timeout in seconds (in this case, to five minutes). This is a wise precaution if there’s a possibility that your script may be handling image files that are large enough to exceed the default script timeout for your web server.
Learning the Tricks
If you want to learn more about ImageMagick, the most promising resource is Michael Still’s book The Definitive Guide to ImageMagick (ISBN 1590595904), published in December 2005, by Apress. It explains how to install and configure ImageMagick for several Linux distributions as well as Microsoft Windows. The chapters cover basic image manipulation, compression, other metadata, ImageMagick tools, artistic transformations, other image transformations, and drawing commands. The book concludes with examples in which ImageMagick is utilized from within programs written in Perl, C, Ruby, and PHP.
The ImageMagick web site offers some documentation. For each of ImageMagick’s ten command-line tools, the site has a page that briefly explains the tool’s purpose, provides examples of its usage, and lists all the command-line options. Each option is linked to more detailed coverage on another page. In addition, there’s a page that’s devoted to the available ImageMagick APIs, for 11 different programming languages, including PHP, Perl, and Java.
To learn more about MagickWand and its commands, you can download the online manual, which is in HTML Help Compiled File format. If you elect to use imagick as your API, you’ll find fewer resources available, mainly comprising the sample code from the examples directory within the download package.
Programmers and web developers often find looking at working code to be the most efficient way to learn a new technology, and ImageMagick is no exception. The code snippets above illustrate all of the fundamental image operations. To see how to perform more sophisticated operations, take a look at Anthony Thyssen’s examples of ImageMagick usage.
All site owners and web developers should already know that with PHP and other scripting languages, their sites’ pages can truly be made dynamic — now they can say the same about their site’s graphics as well!