392 Chapter 19 Generating Images 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); The 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, depending on what you want to draw—lines, arcs, polygons, or text. The drawing functions generally require the following as parameters: n The image identifier n The start and sometimes the end coordinates of what you want to draw n The color you want to draw in n 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. Note 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! 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); 24 525x ch19 1/24/03 2:57 PM Page 392 393 Creating Images The ImageString() function takes some slightly different parameters.The prototype for this function is int imagestring (resource im, int font, int x, int y, string s, int col) It takes as parameters the image identifier, the font, the x and y coordinates to start writ- ing 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 writ- ten 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. Figure 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 24 525x ch19 1/24/03 2:57 PM Page 393 394 Chapter 19 Generating Images This 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 exe- cuted if an HTTP header has already been sent for the page. PHP will send an HTTP header automatically for you as soon as you output anything to the browser. Hence, if you have any echo statements, 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). Cleaning 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); 24 525x ch19 1/24/03 2:57 PM Page 394 395 Using Automatically Generated Images in Other Pages 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. Figure 19.3 The dynamically produced inline image appears the same as a regular image to the end user. 24 525x ch19 1/24/03 2:57 PM Page 395 396 Chapter 19 Generating Images 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. We will also use TrueType fonts so that we can use anti-aliased text.The TrueType font functions 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 ren- dered 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.) Figure 19.4 The front end lets a user choose the button color and type in the required text. 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. The button is generated by a script called make_button.php.This script is shown in Listing 19.2. 24 525x ch19 1/24/03 2:57 PM Page 396 . identifier, the font, the x and y coordinates to start writ- ing 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 paint (x and y), and the color to fill in as parameters. Note 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. that the text writ- ten 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