You need to pass your image identifier and the red, green, and blue RGB values of the color you want to draw into the function.. The function returns a color identifier that we can use t
Trang 13 Outputting the final graphic
4 Cleaning up resources
We’ll begin by looking at a very simple image creation script This script is shown in
Listing 19.1
L ISTING 19.1 simplegraph.php —Outputs a Simple Line Graph with the Label Sales
<?
// set up image
$height = 200;
$width = 200;
$im = ImageCreate($width, $height);
$white = ImageColorAllocate ($im, 255, 255, 255);
$black = ImageColorAllocate ($im, 0, 0, 0);
// draw on image
ImageFill($im, 0, 0, $black);
ImageLine($im, 0, 0, $width, $height, $white);
ImageString($im, 4, 50, 150, “Sales”, $white);
// output image
Header (“Content-type: image/png”);
ImagePng ($im);
// clean up
ImageDestroy($im);
?>
The output from running this script is shown in Figure 19.1
We’ll walk through the steps of creating this image one by one
Creating a Canvas Image
To begin building or changing an image in PHP, you will need to create an image identifier
There are two basic ways to do this One is to create a blank canvas, which you can do with a
call to the ImageCreate()function, as we have done in this script with the following:
$im = ImageCreate($width, $height);
You need to pass two parameters to ImageCreate() The first is the width of the new image,
and the second is the height of the new image The function will return an identifier for the
new image (These work a lot like file handles.)
19
Trang 2F IGURE 19.1
The script draws a black background and then adds a line and a text label for the image.
An alternative way is to read in an existing image file that you can then filter, resize, or add to You can do this with one of the functions ImageCreateFromPNG(),ImageCreateFromJPEG(),
or ImageCreateFromGIF(), depending on the file format you are reading in Each of these takes the filename as a parameter, as in, for example,
$im = ImageCreateFromPNG(“baseimage.png”);
An example is shown later in this chapter using existing images to create buttons on-the-fly
Drawing or Printing Text onto the Image
There are really two stages to drawing or printing text on the image
First, you must select the colors in which you want to draw As you probably already know, colors to be displayed on a computer monitor are made up of different amounts of red, green, and blue light Image formats use a color palette that consists of a specified subset of all the possible combinations of the three colors To use a color to draw in an image, you need to add this color to the image’s palette You must do this for every color you want to use, even black and white
You can select colors for your image by calling the ImageColorAllocate()function You need
to pass your image identifier and the red, green, and blue (RGB) values of the color you want
to draw into the function
In Listing 19.1, we are using two colors: black and white We allocate these by calling
$white = ImageColorAllocate ($im, 255, 255, 255);
$black = ImageColorAllocate ($im, 0, 0, 0);
Trang 3The function returns a color identifier that we can use to access the color later on.
Second, to actually draw into the image, a number of different functions are available,
depend-ing on what you want to draw—lines, arcs, polygons, or text
The drawing functions generally require the following as parameters:
• The image identifier
• The start and sometimes the end coordinates of what you want to draw
• The color you want to draw in
• For text, the font information
In this case, we used three of the drawing functions Let’s look at each one in turn
First, we painted a black background on which to draw using the ImageFill()function:
ImageFill($im, 0, 0, $black);
This function takes the image identifier, the start coordinates of the area to paint (x and y), and
the color to fill in as parameters
19
One thing to note is that the coordinates of the image start from the top-left corner,
which is x=0 , y=0 The bottom-right corner of the image is x=$width , y=$height This
is the opposite of typical graphing conventions, so beware!
NOTE
Next, we’ve drawn a line from the top-left corner (0, 0) to the bottom-right corner ($width,
$height)of the image:
ImageLine($im, 0, 0, $width, $height, $white);
This function takes the image identifier, the start point x and y for the line, the end point, and
then the color, as parameters
Finally, we add a label to the graph:
ImageString($im, 4, 50, 150, “Sales”, $white);
The ImageString()function takes some slightly different parameters The prototype for this
function is
int imagestring (int im, int font, int x, int y, string s, int col)
Trang 4It takes as parameters the image identifier, the font, the x and y coordinates to start writing the text, the text to write, and the color
The font is a number between 1 and 5 These represent a set of built-in fonts As an alternative
to these, you can use TrueType fonts, or PostScript Type 1 fonts Each of these font sets has a corresponding function set We will use the TrueType functions in the next example
A good reason for using one of the alternative font function sets is that the text written by
ImageString()and associated functions, such as ImageChar()(write a character to the image)
is aliased The TrueType and PostScript functions produce anti-aliased text
If you’re not sure what the difference is, look at Figure 19.2 Where curves or angled lines appear in the letters, the aliased text appears jagged The curve or angle is achieved by using a
“staircase” effect In the anti-aliased image, when there are curves or angles in the text, pixels
in colors between the background and the text color are used to smooth the text’s appearance
F IGURE 19.2
Normal text appears jagged, especially in a large font size Anti-aliasing smooths the curves and corners of the letters.
Outputting the Final Graphic
You can output an image either directly to the browser, or to a file
In this example, we’ve output the image to the browser This is a two-stage process First, we need to tell the Web browser that we are outputting an image rather than text or HTML We do this by using the Header()function to specify the MIME type of the image:
Header (“Content-type: image/png”);
Normally when you retrieve a file in your browser, the MIME type is the first thing the Web server sends For an HTML or PHP page (post execution), the first thing sent will be
Content-type: text/html
Trang 5This tells the browser how to interpret the data that follows.
In this case, we want to tell the browser that we are sending an image instead of the usual
HTML output We can do this using the Header()function, which we have not yet discussed
This function sends raw HTTP header strings Another typical application of this is to do
HTTP redirects These tell the browser to load a different page instead of the one requested
They are typically used when a page has been moved For example,
Header (“Location: http://www.domain.com/new_home_page.html “);
An important point to note when using the Header()function is that it cannot be executed if
an HTTP header has already been sent for the page PHP will send an HTTP header
automati-cally for you as soon as you output anything to the browser Hence, if you have any echo
state-ments, or even any whitespace before your opening PHP tag, the headers will be sent, and you
will get a warning message from PHP when you try to call Header() However, you can send
multiple HTTP headers with multiple calls to the Header()function in the same script,
although they must all appear before any output is sent to the browser
After we have sent the header data, we output the image data with a call to
ImagePng ($im);
This sends the output to the browser in PNG format If you wanted it sent in a different format,
you could call ImageJPEG()—if JPEG support is enabled—or ImageGIF()—if you have an
older version of gd You would also need to send the corresponding header first; that is, either
Header (“Content-type: image/jpeg”);
or
Header (“Content-type: image/gif”);
The second option you can use, as an alternative to all the previous ones, is to write the image
to a file instead of to the browser You can do this by adding the optional second parameter to
ImagePNG()(or a similar function for the other supported formats):
ImagePNG($im, $filename);
Remember that all the usual rules about writing to a file from PHP apply (for example, having
permissions set up correctly)
19
Trang 6Cleaning Up
When you’re done with an image, you should return the resources you have been using to the server by destroying the image identifier You can do this with a call to ImageDestroy():
ImageDestroy($im);
Using Automatically Generated Images in Other Pages
Because a header can only be sent once, and this is the only way to tell the browser that we are sending image data, it is slightly tricky to embed any images we create on-the-fly in a regular page Three ways you can do it are as follows:
1 You can have an entire page consist of the image output, as we did in the previous example
2 You can write the image out to a file as previously mentioned, and then refer to it with a normal <IMG>tag
3 You can put the image production script in an image tag
We have covered methods 1 and 2 already Let’s briefly look at method 3
To use this method, you include the image inline in HTML by having an image tag along the lines of the following:
<img src=”simplegraph.php” height=200 width=200 alt=”Sales going down”>
Instead of putting in a PNG, JPEG, or GIF directly, put in the PHP script that generates the image
in the SRC tag This will be retrieved and the output added inline, as shown in Figure 19.3
Using Text and Fonts to Create Images
We’ll look at a more complicated example It is useful to be able to create buttons or other images for your Web site automatically You can build simple buttons based on a rectangle of background color using the techniques we’ve already discussed
In this example, however, we’ll generate buttons using a blank button template that allows us
to have features like beveled edges and so on, which are a good deal easier to generate using Photoshop, the GIMP, or some other graphics tool With the image library in PHP, we can begin with a base image and draw on top of that
Trang 7F IGURE 19.3
The dynamically produced inline image appears the same as a regular image to the end user.
We will also use TrueType fonts so that we can use anti-aliased text The TrueType font
func-tions have their own quirks, which we’ll discuss
The basic process is to take some text and generate a button with that text on it The text will
be centered both horizontally and vertically on the button, and will be rendered in the largest
font size that will fit on the button
We’ve built a front end to the button generator for testing and experimenting This interface is
shown in Figure 19.4 (We have not included the HTML for this form here as it is very simple,
but you can find it on the CD in design_button.html.)
You could use this type of interface for a program to automatically generate Web sites You
could also call the script we write in an inline fashion, to generate all a Web site’s buttons
on-the-fly!
Typical output from the script is shown in Figure 19.5
19
Trang 8F IGURE 19.4
The front end lets a user choose the button color and type in the required text.
F IGURE 19.5
A button generated by the make_button.php script.
The button is generated by a script called make_button.php This script is shown in Listing 19.2
L ISTING 19.2 make_button.php —This Script Can Be Called from the Form in design_button.html or from Within an HTML Image Tag
<?
// check we have the appropriate variable data // variables are button-text and color
Trang 9if (empty($button_text) || empty($color))
{
echo “Could not create image - form not filled out correctly”;
exit;
}
// create an image of the right background and check size
$im = imagecreatefrompng (“$color-button.png”);
$width_image = ImageSX($im);
$height_image = ImageSY($im);
// Our images need an 18 pixel margin in from the edge image
$width_image_wo_margins = $width_image - (2 * 18);
$height_image_wo_margins = $height_image - (2 * 18);
// Work out if the font size will fit and make it smaller until it does
// Start out with the biggest size that will reasonably fit on our buttons
$font_size = 33;
do
{
$font_size ;
// find out the size of the text at that font size
$bbox=imagettfbbox ($font_size, 0, “arial.ttf”, $button_text);
$right_text = $bbox[2]; // right co-ordinate
$left_text = $bbox[0]; // left co-ordinate
$width_text = $right_text - $left_text; // how wide is it?
$height_text = abs($bbox[7] - $bbox[1]); // how tall is it?
} while ( $font_size>8 &&
( $height_text>$height_image_wo_margins ||
$width_text>$width_image_wo_margins ) );
if ( $height_text>$height_image_wo_margins ||
$width_text>$width_image_wo_margins ) {
// no readable font size will fit on button
echo “Text given will not fit on button.<BR>”;
}
else
19
L ISTING 19.2 Continued
Trang 10{ // We have found a font size that will fit // Now work out where to put it
$text_x = $width_image/2.0 - $width_text/2.0;
$text_y = $height_image/2.0 - $height_text/2.0 ;
if ($left_text < 0)
$text_x += abs($left_text); // add factor for left overhang
$above_line_text = abs($bbox[7]); // how far above the baseline?
$text_y += $above_line_text; // add baseline factor
$text_y -= 2; // adjustment factor for shape of our template
$white = ImageColorAllocate ($im, 255, 255, 255);
ImageTTFText ($im, $font_size, 0, $text_x, $text_y, $white, “arial.ttf”,
$button_text);
Header (“Content-type: image/png”);
ImagePng ($im);
} ImageDestroy ($im);
?>
This is one of the longest scripts we’ve looked at so far Let’s step through it section by sec-tion We begin with some basic error checking, and then set up the canvas on which we’re going to work
Setting Up the Base Canvas
In Listing 19.2, rather than starting from scratch, we will start with an existing image for the button We have a choice of three colors in the basic button: red (red-button.png), green (green-button.png), and blue (blue-button.png)
The user’s chosen color is stored in the $colorvariable from the form
We begin by setting up a new image identifier based on the appropriate button:
$im = imagecreatefrompng (“$color-button.png”);
L ISTING 19.2 Continued