With the assistance of the GD library, you can use PHP to create applications that use dynamic images to display stock quotes, reveal poll results, monitor system performance, and even create games. However, it's not like using Photoshop or GIMP; you can't draw a line by moving your mouse. Instead, you need to precisely specify a shape's type, size, and position.
GD has an existing API, and PHP tries to follows its syntax and function-naming conventions. So if you're familiar with GD from other languages, such as C or Perl, you can easily use GD with PHP. If GD is new to you, it may take a few minutes to figure it out, but soon you'll be drawing like Picasso.
The feature set of GD varies greatly depending on which version of GD you're running and which features were enabled during configuration. GD can support GIFs, JPEGs, PNGs, and WBMPs. GD reads in PNGs and JPEGs with almost no loss in quality. Also, GD supports PNG alpha channels, which allow you to specify a transparency level for each pixel.
Besides supporting multiple file formats, GD lets you draw pixels, lines, rectangles, polygons, arcs, ellipses, and circles in any color you want. Recipe 17.1 covers straight shapes, while Recipe 17.2 covers the curved ones. To fill shapes with a pattern instead of a solid color, see Recipe 17.3.
You can also draw text using a variety of font types, including built-in, TrueType, and PostScript Type 1 fonts. Recipe 17.4 shows the ins and outs of the three main text-drawing functions, and Recipe 17.5 shows how to center text within a canvas. These two recipes form the basis for Recipe 17.6, which combines an image template with real-time data to create dynamic images. GD also lets you make transparent GIFs and PNGs. Setting a color as transparent and using transparencies in patterns are discussed in Recipes 19.9.
To extract image metadata from digital photos and other images that store information using the EXIF standard, read Recipe 17.8.
Recipe 17.9 moves away from GD and shows how to securely serve images by restricting user access. Last, there's an example application taking poll results and producing a dynamic bar graph showing what percentage of users voted for each answer.
All these features work with the version of GD bundled with PHP 5.1. If you have an earlier version, you should not have a problem. However, if a particular recipe needs a specific version of GD, it's noted in the recipe.
GD is available for download from the official GD site at http://www.boutell.com/gd/. The GD section of the online PHP Manual at http://www.php.net/image also lists the location of the additional libraries necessary to provide support for JPEGs and Type 1 fonts. However, the PHP team has recently taken over development of the GD library, so expect that it will be increasingly easy to use PHP and GD.
There are two easy ways to see which version, if any, of GD is installed on your server and how it's configured. One way is to call phpinfo( ) . You should see --with-gd at the top under "Configure Command"; further down the page there is also a section titled "gd" that has more information about which version of GD is installed and what features are enabled. The other option is to check the return value of function_exists('imagecreate'). If it returns true, GD is installed. The imagetypes( ) function returns a bit field indicating which graphics formats are available. See http://www.php.net/imagetypes for more on how to use this function. If you want to use a feature that isn't enabled, you need to rebuild PHP yourself or get your ISP to do so.
The basic image generation process has three steps: creating the image, adding graphics and text to the canvas, and displaying or saving the image. For example:
$image = ImageCreate(200, 50); $background_color = ImageColorAllocate($image, 255, 255, 255); // white $gray = ImageColorAllocate($image, 204, 204, 204); // gray ImageFilledRectangle($image, 50, 10, 150, 40, $gray); header('Content-type: image/png'); ImagePNG($image);
The output of this code, which prints a gray rectangle on a white background, is shown in Figure 17-1.
A gray rectangle on a white background
To begin, you create an image canvas. The ImageCreate( ) function doesn't return an actual image. Instead, it provides you with a handle to an image; it's not an actual graphic until you specifically tell PHP to write the image out. Using ImageCreate( ), you can juggle multiple images at the same time.
The parameters passed to ImageCreate( ) are the width and height of the graphic in pixels. In this case, it's 200 pixels across and 50 pixels high. Instead of creating a new image, you can also edit existing images. To open a graphic, call ImageCreateFromPNG( ) or a similarly named function to open a different file format. The filename is the only argument, and files can live locally or on remote servers:
// open a PNG from the local machine $graph = ImageCreateFromPNG('/path/to/graph.png'); // open a JPEG from a remote server $icon = ImageCreateFromJPEG('http://www.example.com/images/icon.jpeg');
Once you have an editable canvas, you get access to drawing colors by calling ImageColorAllocate( ) :
$background_color = ImageColorAllocate($image, 255, 255, 255); // white $gray = ImageColorAllocate($image, 204, 204, 204); // gray
The ImageColorAllocate( ) function takes an image handle to allocate the color to three integers. The three integers each range from 0 to 255 and specify the red, green, and blue components of the color. This is the same RGB color combination that is used in HTML to set a font or background color. So white is 255, 255, 255; black is 0, 0, 0; and everything else is somewhere in between.
The first call to ImageAllocateColor( ) sets the background color. Additional calls allocate colors for drawing lines, shapes, or text. Therefore, set the background color to 255, 255, 255 and then grab a gray pen with ImageAllocateColor($image, 204, 204, 204). It may seem odd that the background color is determined by the order ImageAllocateColor( ) is called and not by a separate function. But that's how things work in GD, so PHP respects the convention.
Call ImageFilledRectangle( ) to place a box onto the canvas. ImageFilledRectangle( ) takes many parameters: the image to draw on, the x and y coordinates of the upper left corner of the rectangle, the x and y coordinates of the lower right corner of the rectangle, and finally, the color to use to draw the shape. Tell ImageFilledRectangle( ) to draw a rectangle on $image, starting at (50,10) and going to (150,40), in the color gray:
ImageFilledRectangle($image, 50, 10, 150, 40, $gray);
Unlike a Cartesian graph, (0,0) is not in the lower left corner; instead, it's in the upper left corner. So the vertical coordinate of the spot 10 pixels from the top of a 50-pixel-high canvas is 10 because it's 10 pixels down from the top of the canvas. It's not 40, because you measure from the top down, not the bottom up. And it's not -10, because down is considered the positive direction, not the negative one.
Now that the image is all ready to go, you can serve it up. First, send a Content-Type header to let the browser know what type of image you're sending. In this case, display a PNG. Next, have PHP write the PNG image out using ImagePNG( ). Once the image is sent, your task is over:
header('Content-Type: image/png'); ImagePNG($image);
To write the image to disk instead of sending it to the browser, provide a second argument to ImagePNG( ) with where to save the file:
Since the file isn't going to the browser, there's no need to call header( ). Make sure to specify a path and an image name, and be sure PHP has permission to write to that location.
PHP cleans up the image when the script ends, but if you wish to manually deallocate the memory used by the image, calling ImageDestroy($image) forces PHP to get rid of the image immediately.