16.1 Creating Dynamic Images


PHP supports many functions for generating or modifying images on-the-fly. These functions are mostly built on the GD library, which you can download from http://www.boutell.com/gd. In most binary distributions of PHP, the GD module is included. If you are compiling your binaries yourself, the GD module has to be enabled at compile time using --with-gd when running configure. In addition, support for JPG should be enabled.

After you have compiled PHP to your needs, you can start working with the module. In this section you will learn to perform all basic operations when working with images and you will also see how text can be processed efficiently.

16.1.1 Basic Operations

The first thing to do when generating a picture is to create it. With PHP, this can easily be done with the help of the ImageCreate function. Just define the size of the image and a handle will be returned. This handle is used for all other operations.

The second thing to do is to allocate colors. This is an important point and you will see why allocating a color is a critical operation. To allocate a color, pass the handle of the image as well as the definition of the color to the function. Finally, the image has to be sent to the browser or stored in a file. The next example shows how to create an image. The background color of the image is set to black:

 <?php         $image = ImageCreate (300, 300);         if      (!$image)         {                 echo "picture cannot be generated<br>\n";         }         else         {                 header ("Content-type: image/png");                 $white = ImageColorAllocate($image, 255, 255, 255);                 $black = ImageColorAllocate($image, 0, 0, 0);                 $red = ImageColorAllocate($image, 255, 0, 0);                 $blue = ImageColorAllocate($image, 0, 0, 255);                 $status = imagefill($image, 1, 1, $black);                 ImagePng($image);         } ?> 

When executing the script, the image will be displayed by the browser directly. The reason for that is the header information. As you can see, the header tells the browser to treat the data from the Web server as an image. If other data is sent to the browser, it will not be treated as HTML because the browser is prepared for receiving a PNG file.

Sometimes it is necessary to load a picture from a file and to perform some modifications before sending it to the browser. Therefore PHP provides a list of functions such as ImageCreateFromJpeg. This function reads the image and returns a handle to it. In the next step the image can be displayed or modified. The following listing shows how an image can be read and sent to a file:

 <?php         $image = ImageCreateFromJpeg ('author_hans.jpg');         if      (!$image)         {                 echo "picture cannot be loaded<br>\n";         }         else         {                 header ("Content-type: image/jpeg");                 ImageJpeg($image);         } ?> 

This time the function for displaying the image is not ImagePng but ImageJpeg because a JPEG file has been read. In Figure 16.1 you can see what the result might look like.

Figure 16.1. The author of this chapter.

graphics/16fig01.jpg

PHP supports not only PNG and JPEG, but in addition to these two image formats, PHP supports GD, GD2, GIF, WBMP, XBM, and XPM.

To find out which types of images your current PHP installation supports, you can use the ImageTypes function as shown in the next listing:

 <?php         if (ImageTypes() & IMG_PNG) { echo "PNG is supported<br>"; }         if (ImageTypes() & IMG_GIF) { echo "GIF is supported<br>"; }         if (ImageTypes() & IMG_JPG) { echo "JPG is supported<br>"; }         if (ImageTypes() & IMG_WBMP) { echo "WBMP is supported<br>"; } ?> 

In this example three lines will be displayed because GIF has been compiled into your PHP binaries:

 PNG is supported JPG is supported WBMP is supported 

The installation you are currently working on might return different values. The output of this script depends greatly on your specific installation and distribution.

To find out how many colors the palette of your image contains, PHP provides the ImageColorsTotal function:

 <?php         $image = ImageCreateFromJpeg ('author_hans.jpg');         echo "Number of colors in the picture: ".ImageColorsTotal($image); ?> 

In this scenario 256 is returned:

 Number of colors in the picture: 256 

To retrieve the color of a certain pixel in the image, you can use a script like the next one:

 <?php         $image = ImageCreateFromJpeg ('author_hans.jpg');         echo "Color at 100/100: ".imagecolorat($image, 100, 100); ?> 

PHP returns 98, which is the position of the color in the palette:

 Color at 100/100: 98 

Sometimes it is necessary to retrieve information about the size of a picture. Just think of an application that adds text at the center of an image. You will need the size of the image to compute the center of the image and to locate the text correctly. To gather the size of a picture, PHP supports the getimagesize function as shown in the next listing:

 <?php         $data = getimagesize('author_hans.jpg');         echo "x-coordinates: $data[0]<br>\n";         echo "y-coordinates: $data[1]<br>\n"; ?> 

$data contains two values. The first field contains the number of pixels in the x coordinate. The second value contains information about the y-axis:

 x-coordinates: 169 y-coordinates: 255 

In this example 169 and 255 are returned. If you try this on your machine, the values might differ because of different pictures used as input. You can achieve the same result with the help of imagesx and imagesy:

 <?php         $image = ImageCreateFromJpeg ('author_hans.jpg');         echo "width: ".imageSX($image)."<br>";         echo "height: ".imageSY($image)."<br>"; ?> 

The output of the script contains the same values:

 width: 169 height: 255 

Now that you have seen how to perform basic operations, it is time to see how you can copy parts of a picture with the help of PHP's GD interface. Let's take a look at the code of the next sample application:

 <?php         $source = ImageCreateFromJpeg ('author_hans.jpg');         $destination = ImageCreate(200, 200);         $white = ImageColorAllocate($destination, 255, 255, 255);         imagefill($destination, 199, 199, $white);         $stat = ImageCopy($destination, $source, 0, 0, 50, 50, 100, 100);         header ("Content-type: image/png");         ImagePng($destination); ?> 

First the image is loaded. The handle of that image is called $source because this is the source file where the data we are going to copy will be taken from. In the next step a new picture is created and the background of the picture is painted white. To copy a part of the source picture into the picture you have just created, you can use the ImageCopy command. The first parameter defines the destination picture. The second parameter tells PHP where to take the data from. The third and the fourth parameter define the coordinates where the image will be placed. Parameters number five and six specify the size of the fragment you want to copy. Finally the last two parameters define the coordinates from which the image should be copied.

At the end of the script the fragment is displayed. In Figure 16.2 you can see what the result looks like.

Figure 16.2. A piece of the author's picture.

graphics/16fig02.jpg

The next thing that is often important is PHP's ability to merge pictures. In more complex operations, one picture might have to be put on top of another picture. You can easily perform operations like that using the ImageCopyMerge function. Let's take a look at the next piece of code:

 <?php         header ("Content-type: image/jpeg");         $one = ImageCreateFromJpeg ('author_hans.jpg');         $two = ImageCreateFromJpeg ('logo.jpg');         $stat = ImageCopyMerge($one, $two, 0, 120,                 0, 0, imagesx($two), imagesy($two), 50);         ImageJpeg($one); ?> 

First two pictures are opened. The first picture is already familiar to you. The second picture is shown in Figure 16.3.

Figure 16.3. Logo.jpg Europe's new currency.

graphics/16fig03.jpg

The two pictures should be merged. Therefore ImageCopyMerge is called with a list of parameters. The next listing shows the parameters and their meaning in the same order they occur in the function call:

  • src_im Defines the source image.

  • dst_im Defines the destination image (the picture containing the output).

  • dst_x and dst_y Defines the position of the graphics in the destination image.

  • src_x and src_y Defines the location to take the image from.

  • src_w and src_h Defines the size of the image merged by the command.

  • pct This parameter defines the percentage of the image being merged. A setting of 100% means the same as copy in this case the underlying image cannot be seen any more.

If you execute the script, you can see that the Euro symbol lies on top of the author, which might be a good omen for the book. The output is shown in Figure 16.4.

Figure 16.4. Merging two pictures.

graphics/16fig04.jpg

In this example the pictures are merged without taking the colors of the two images into consideration. The next example shows how the second image can be used as a grayscale picture:

 <?php         header ("Content-type: image/jpeg");         $one = ImageCreateFromJpeg ('author_hans.jpg');         $two = ImageCreateFromJpeg ('logo.jpg');         $stat = ImageCopyMergeGray($one, $two, 0, 120,                 0, 0, imagesx($two), imagesy($two), 50);         ImageJpeg($one);($image); ?> 

The result will look slightly different because of the grayscale merging.

16.1.2 Drawing Components

In this section you will learn to draw simple geometric objects. For many applications this is essential. Just think of an application that draws graphs. A graph consists of many components such as lines, text, or polygons. Every component of the graph can easily be added to the scenery using PHP scripts.

Before you can start building applications that are that complex, you will take a look at some examples. Let's start with the first piece of code:

 <?php         header ("Content-type: image/jpeg");         $image = ImageCreate(200, 200);         $white = ImageColorAllocate($image, 255, 255, 255);         $black = ImageColorAllocate($image, 0, 0, 0);         $stat = ImageFill($image, 0, 0, $white);         $stat = ImageLine($image, 0, 0, 199, 199, $black);         ImageJpeg($image); ?> 

After creating an image, two colors are allocated and the background of the image is painted white. Finally a black line is displayed on the screen before sending the picture to the browser. The line is drawn from the left-upper edge to the lower-right edge of the picture. PHP uses the default style for lines. To modify these settings a variety of functions are provided. However, most of these functions are only available on systems with GD 2.01 or higher installed. The problem with GD 2.01 is that it has some bugs when working with anti-aliasing. Therefore we strongly recommend not using this version of the GD module. In most Linux distributions GD 1.x is still included, so GD 2 is not that widely used yet (at the time this book was written). Figure 16.5 shows the output of the preceding script.

Figure 16.5. A line.

graphics/16fig05.jpg

It's boring to draw nothing but lines, but take a look at some more objects that can be created using simple PHP functions:

 <?php         header ("Content-type: image/jpeg");         $image = ImageCreate(200, 200);         $white = ImageColorAllocate($image, 255, 255, 255);         $black = ImageColorAllocate($image, 0, 0, 0);         $stat = ImageFill($image, 0, 0, $white);         # drawing parts of an ellipse         imagearc($image, 100, 50, 80, 40, 20, 300, $black);         # drawing a circle         imagearc($image, 100, 150, 60, 60, 00, 360, $black);         # drawing a polygon         $points = array(0,0, 0,199, 199,199, 199,0);         ImagePolygon($image, $points, 4, $black);         ImagePng($image); ?> 

After allocating some color and painting the background of the image, as you have already seen, the script starts with displaying a part of an ellipse. The second and third parameters define the location of the ellipse. The fourth parameter tells PHP the width of the ellipse, and the fifth parameter contains the height of the object. Finally the starting angle and the ending angle as well as the color are defined. This way it is possible to draw incomplete ellipses as well as full ellipses. To draw a circle, the command parameters have to be modified to satisfy the demands of a circle.

The ImagePolygon function draws a polygon. To define the polygon nonambiguously, the handle to the image, an array of points, the number of points, and the color have to be defined.

Figure 16.6 shows the result of the script.

Figure 16.6. A set of objects.

graphics/16fig06.jpg

To draw an ellipse, you can also use imageellipse, but it is only available on systems where GD 2.02 or higher is installed.

To draw rectangles, PHP provides a function called imagefilledrectangle. It draws a filled rectangle it is not possible to draw a rectangle without filling it. The next example shows how to draw rectangles:

 <?php         header ("Content-type: image/jpeg");         $image = ImageCreate(200, 200);         $white = ImageColorAllocate($image, 255, 255, 255);         $black = ImageColorAllocate($image, 0, 0, 0);         $stat = ImageFill($image, 0, 0, $white);         imagefilledrectangle ($image, 30, 30, 60, 60, $black);         imagefilledrectangle ($image, 90, 30, 120, 60, $black);         imagefilledrectangle ($image, 30, 100, 120, 130, $black);         ImagePng($image); ?> 

The imagefilledrectangle function needs six parameters. The first parameter points to the image you want to process. The second and third parameters define the left-upper edge of the rectangle. The next two parameters contain information about the right-lower corner of the object. The last parameter contains the color.

16.1.3 Working with Fonts

When working with dynamically generated graphics, it is often necessary to work with text. Therefore PHP provides various sets of functions capable of processing text fast and efficiently. However, these groups of functions have advantages and disadvantages. Depending on what you need, you have to decide which group of functions to use.

One set of functions to work with is PostScript 1 functions. These functions must be enabled at compile time. By setting the two flags --with-ttf[=DIR] and --with-t1lib[=DIR] when running configure, you can enable TrueType. If it is not enabled at compile time, an error like the one in the next listing is displayed:

 Warning: ImagePsLoadFont: No T1lib support in this PHP build in 

In this book you will not learn about FreeType 1 functions, but you will take a closer look at functions based on FreeType 2.

To enable FreeType 2 at compile time, you have to use the --enable-gd-native-ttf and the --with-freetype-dir flags.

If you have compiled the code correctly, you can run the script in the next listing. If you are using a binary distribution of PHP, you have to run the phpinfo function to find out if FreeType 2 is supported. All these things sound complicated, but keep in mind that PHP does not natively support graphics PHP is just a framework for a list of functions.

Let's take a look at some code:

 <?php         $image = ImageCreate(350, 150);         $white = ImageColorAllocate($image, 255, 255, 255);         $black = ImageColorAllocate($image, 0, 0, 0);         $stat = ImageFill($image, 0, 0, $white);         $font = "/usr/share/fonts/default/TrueType/timb____.ttf";         $text = "Check out";         $pos = imagettftext($image, 30, 0, 30, 50, $black, $font, $text);         $text = "www.postgresql.at";         $pos = imagettftext($image, 30, 0, 30, 90, $black, $font, $text);         if      (!$pos)         {                 echo "cannot use Freetype 2<br>\n";         }         else         {                 header ("Content-type: image/png");                 ImagePng($image);         } ?> 

The imagettftext function does everything you need. Just define the place where you want the text to be displayed (parameters four and five), the size of the text (parameter number two), the angle (parameter number three), the color, the font, and the text you want to be displayed. The application in the preceding listing displays two items of text and checks whether the text has been displayed correctly. The picture is shown in Figure 16.7.

Figure 16.7. Some simple text based on FreeType 2.

graphics/16fig07.jpg

Sometimes you might want to display various lines of text at the center of an image. Therefore you can use a temporary image and the return values of imagettftext. Let's take a look at the next piece of code:

 <?php         # defining size; creating images; allocating colors         $xsize = 350;         $ysize = 150;         $image = ImageCreate($xsize, $ysize);         $tmp = ImageCreate($xsize, $ysize);         $white = ImageColorAllocate($image, 255, 255, 255);         $black = ImageColorAllocate($image, 0, 0, 0);         $stat = ImageFill($image, 0, 0, $white);         $font = "/usr/share/fonts/default/TrueType/timb____.ttf";         # drawing border         $points = array(0,0, 0,$ysize-1, $xsize-1,$ysize-1, $xsize-1,0);         ImagePolygon($image, $points, 4, $black);         # writing text         writetext("Greetings", 20, 30);         writetext("From", 20, 75);         writetext("Vienna", 40, 130);         header ("Content-type: image/png");         ImagePng($image); function writetext($text, $size, $ypos) {         global $image, $tmp, $font, $black, $xsize;         $pos = imagettftext($tmp, $size, 0, 0, 0, $black, $font, $text);         $width = $pos[2] - $pos[0];         $height = $pos[3] - $pos[1];         $xpos = $xsize/2 - $pos[2]/2;         $pos = imagettftext($image, $size, 0, $xpos, $ypos, $black,                 $font, $text); } ?> 

First two images are created. One of the images will be the working image. The second one will be a temporary image for computing the size of the text written into the image. After allocating some colors and defining the fonts, a border will be drawn around the image to make it easier for you to see where the image starts and ends. When drawing the border, make sure that you subtract 1 from the right and lower coordinates of the picture because PHP starts counting the coordinates of the image with zero, so the 200th element has index number 199.

In the next step the writetext function is called. This function needs three parameters. The first one contains the text you want to be displayed. The second one defines the size of the text, and parameter number three tells the function which y coordinate to use when displaying the text.

To compute the size of the text you want to be displayed, the text is added to the temporary image. The return value of the function is then used to compute the center of the image. $pos contains the coordinates of the edge of the text added to the image. Therefore it is an easy task to compute the appropriate coordinates before adding the text to the real image. At the end of the function imagettftext is called.

writetext is called three times and after that the image is sent to the browser. The result can be seen in Figure 16.8.

Figure 16.8. Text at the center of the image.

graphics/16fig08.jpg

Up to now you have seen that the text does not have to be angular. The next example shows how you can modify the way the text is displayed by defining an angle:

 <?php         $xsize = 350; $ysize = 150;         $image = ImageCreate($xsize, $ysize);         $white = ImageColorAllocate($image, 255, 255, 255);         $black = ImageColorAllocate($image, 0, 0, 0);         $stat = ImageFill($image, 0, 0, $white);         $font = "/usr/share/fonts/default/TrueType/timb____.ttf";         header ("Content-type: image/png");         $pos = imagettftext($image, 30, 20, 50, 100, $black,                 $font, "PostgreSQL");         ImagePng($image); ?> 

Figure 16.9 shows what comes out when the script is executed.

Figure 16.9. Angular text.

graphics/16fig09.jpg

As you can see, processing text with the help of the GD module is not difficult. However, if you have to perform complex operations, it is worth taking a look at some alternative solutions.

16.1.4 Alternative Solutions

If the operations you want to perform with images are more complex, you cannot use GD. In this case alternative solutions have to be found. In Unix there are many ways to generate dynamic images on-the-fly. Unix is often said to be an operating system that cannot handle graphics, which is not true in many cases. The concepts of Unix make it easy to combine software products of all kinds with each other, and this makes Unix a powerful tool for almost all types of computing including working with graphics.

In this section you will get a few hints about how to build even more powerful applications.

16.1.4.1 ImageMagick

For converting pictures from one image into another, you can use ImageMagick. ImageMagick is a robust collection of tools and libraries to read, write, and manipulate images in many image formats including popular formats such as TIFF, JPEG, PNG, PDF, PhotoCD, and GIF. All together more than 68 formats are supported. In most cases you will find the right converter or filter to achieve your target.

Another important feature of ImageMagick is its ability to combine various images into an animated GIF. When building Web sites, this can be essential and a great benefit.

Usually ImageMagick is used in combination with system calls because this is the only way to start external programs.

You can download ImageMagick from http://www.imagemagick.org.

16.1.4.2 Gimp

Gimp is the most powerful and most flexible piece of software ever written for working with graphics under Unix. Not only does it provide a lot of functionality, but it is also a flexible and well-designed piece of software. The flexibility of Gimp especially makes this product quite powerful, and interacting with other software is easy.

An additional advantage of Gimp is its scripting interface. You can execute entire programs performing complex operations and computations. Scripts can be executed by Gimp noninteractively, which means that you can write batch jobs performing exactly those operations you will need.

Let's take a look at the command-line parameters provided by Gimp:

 gimp [-h] [--help] [-v] [--version] [-b] [--batch <commands>]    [-g] [--gimprc <gim prc>]  [-n]  [--no-interface]  [-r]    [--restore-session]  [--no-data]  [--verbose]    [--no-shm]   [--no-xshm]  [--display  display]    [--no-splash]  [--no-splash-image]     [--debug-handlers]    [--console-messages] [--system-gimprc <gimprc>]    [filename]... 

As you can see, the --batch command can be used to execute scripts.

When working with Gimp, you have to get used to some specifics of the onboard programming interfaces. In the case of the interactive Script-Fu interface, some aspects concerning computation might not be familiar to you.

Gimp's interactive shell is shown in Figure 16.10.

Figure 16.10. Gimp's interactive shell.

graphics/16fig10.jpg

As you can see, Gimp can be used as a pocket calculator. Most of you won't use a graphics engine as a pocket calculator, but it shows what you can do with Gimp.

For a full reference of Gimp's functions, check out the manual, which can be found at http://manual.gimp.org. As a rule of thumb, you can say that everything you can do with Gimp interactively can also be done with scripts.

Feel free to experiment with the software, and you will soon see that you can generate all kinds of images on the fly efficiently.



PHP and PostgreSQL. Advanced Web Programming2002
PHP and PostgreSQL. Advanced Web Programming2002
ISBN: N/A
EAN: N/A
Year: 2004
Pages: 201

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net