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 GD you're running and which
features were enabled during configuration. Versions of GD up to 1.6 supported
reading and writing GIFs, but this code was removed due
to patent problems. Instead, newer versions of GD support JPEGs, PNGs, and WBMPs. Because
PNGs are generally smaller than GIFs, allow you to use many more colors, have
built-in gamma correction, and are supported by all major web browsers, the lack
of GIF support is classified as a feature, not a bug. For more on PNG, go to http://www.libpng.org/pub/png/ or read Chapter 21, "PNG
Format," of Web Design in a Nutshell written by
Jennifer Niederst (O'Reilly).
Besides supporting multiple file
formats, GD lets you draw pixels, lines, rectangles, polygons, arcs, ellipses,
and circles in any color you want. Section 15.2 covers straight shapes, while Section 15.3 covers the curved ones. To fill shapes with a pattern instead of a
solid color, see Section 15.4.
You can also draw text using a variety
of font types, including built-in, TrueType, and PostScript Type 1 fonts. Section 15.5 shows the ins and outs of the three main text-drawing functions, and Section 15.6 shows how to center text within a canvas. These two recipes form the
basis for Section 15.7, 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 Section 15.8.
Section 15.9 moves away from GD and shows how to securely serve images by
restricting user access. Last, we provide 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 GD 1.8.4, which is the latest
stable version of the library. If you have an earlier version, you should not
have a problem. However, if a particular recipe needs a specific version of GD,
we note it in the recipe.
PHP also supports GD 2.x, which, as of this writing, is still
in beta. Despite its beta status, the new version is relatively stable and has
many new features. In particular, Version 2.x allows true-color images, which
lets GD read in PNGs and JPEGs with almost no loss in quality. Also, GD 2.x
supports PNG alpha channels, which allow you to specify a transparency level for
each pixel.
Both versions of GD are 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.
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 15-1.
Figure 15-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 and 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, we 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:
ImagePng($image, '/path/to/your/new/image.png');
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.
