PHP CookBook Free Open Book

PHP CookBook

Previous Section Next Section

Recipe 15.6 Drawing Centered Text

15.6.1 Problem

You want to draw text in the center of an image.

15.6.2 Solution

Find the size of the image and the bounding box of the text. Using those coordinates, compute the correct spot to draw the text.

For built-in GD fonts, use the pc_ImageStringCenter( ) function shown in Example 15-1.

Example 15-1. pc_ImageStringCenter( )
function pc_ImageStringCenter($image, $text, $font) {
    
    // font sizes
    $width  = array(1 => 5, 6, 7, 8, 9);
    $height = array(1 => 6, 8, 13, 15, 15);

    // find the size of the image
    $xi = ImageSX($image);
    $yi = ImageSY($image);

    // find the size of the text
    $xr = $width[$font] * strlen($text);
    $yr = $height[$font];

    // compute centering
    $x = intval(($xi - $xr) / 2);
    $y = intval(($yi - $yr) / 2);

    return array($x, $y);
}

For example:

list($x, $y) = pc_ImageStringCenter($image, $text, $font);
ImageString($image, $font, $x, $y, $text, $fore);

For PostScript fonts, use the pc_ImagePSCenter( ) function shown in Example 15-2.

Example 15-2. pc_ImagePSCenter( )
function pc_ImagePSCenter($image, $text, $font, $size, $space = 0,
                           $tightness = 0, $angle = 0) {

    // find the size of the image
    $xi = ImageSX($image);
    $yi = ImageSY($image);

    // find the size of the text
    list($xl, $yl, $xr, $yr) = ImagePSBBox($text, $font, $size,
                                     $space, $tightness, $angle);

    // compute centering
    $x = intval(($xi - $xr) / 2);
    $y = intval(($yi + $yr) / 2);

    return array($x, $y);
}

For example:

list($x, $y) = pc_ImagePSCenter($image, $text, $font, $size);
ImagePSText($image, $text, $font, $size, $fore, $back, $x, $y);

For TrueType fonts, use the pc_ImageTTFCenter( ) function shown in Example 15-3.

Example 15-3. pc_ImageTTFCenter( )
function pc_ImageTTFCenter($image, $text, $font, $size) {

    // find the size of the image
    $xi = ImageSX($image);
    $yi = ImageSY($image);

    // find the size of the text
    $box = ImageTTFBBox($size, $angle, $font, $text);

    $xr = abs(max($box[2], $box[4]));
    $yr = abs(max($box[5], $box[7]));

    // compute centering
    $x = intval(($xi - $xr) / 2);
    $y = intval(($yi + $yr) / 2);

    return array($x, $y);
}

For example:

list($x, $y) = pc_ImageTTFCenter($image, $text, $font, $size);
ImageTTFText($image, $size, $angle, $x, $y, $fore, $font, $text);

15.6.3 Discussion

All three solution functions return the x and y coordinates for drawing. Of course, depending on font type, size, and settings, the method used to compute these coordinates differs.

For PostScript Type 1 fonts, pass pc_ImagePSCenter( ) an image allocated from ImageCreate( ) (or one of its friends) and a number of parameters to specify how to draw the text. The first three parameters are required: the text to be drawn, the font, and the font size. The next three are optional: the space in a font, the tightness between letters, and an angle for rotation in degrees.

Inside the function, use ImageSX( ) and ImageSY( ) to find the size of the canvas; they return the width and height of the graphic. Then call ImagePSBBox( ) . It returns four integers: the x and y coordinates of the lower-leftmost location the text and the x and y coordinates of the upper-rightmost location. Because the coordinates are relative to the baseline of the text, it's typical for these not to be 0. For instance, a lowercase "g" hangs below the bottom of the rest of the letters; so, in that case, the lower left y value is negative.

Armed with these six values, we can now calculate the correct centering values. Because coordinates of the canvas have (0,0) in the upper left corner, but ImagePSBText( ) wants the lower left corner, the formula for finding $x and $y isn't the same. For $x, we take the difference between the size of the canvas and the text. This gives the amount of whitespace that surrounds the text. Then we divide that number by two, to find the number of pixels we should leave to the left of the text. For $y, we do the same, but add $yi and $yr. By adding these numbers, we can find the coordinate of the far side of the box, which is what is needed here because of the inverted way the y coordinate is entered in GD.

We intentionally ignore the lower left coordinates in making these calculations. Because the bulk of the text sits above the baseline, adding the descending pixels into the centering algorithm actually worsens the code; it appears off-center to the eye.

To center text, put it together like this:

function pc_ImagePSCenter($image, $text, $font, $size, $space = 0,
                           $tightness = 0, $angle = 0) {

    // find the size of the image
    $xi = ImageSX($image);
    $yi = ImageSY($image);

    // find the size of the text 
    list($xl, $yl, $xr, $yr) = ImagePSBBox($text, $font, $size,
                                     $space, $tightness, $angle);

    // compute centering 
    $x = intval(($xi - $xr) / 2);
    $y = intval(($yi + $yr) / 2);

    return array($x, $y);
}

$image = ImageCreate(500,500);
$text = 'PHP Cookbook Rules!';
$font = ImagePSLoadFont('/path/to/font.pfb');
$size = 20;
$black = ImageColorAllocate($image, 0, 0, 0);
$white = ImageColorAllocate($image, 255, 255, 255);

list($x, $y) = pc_ImagePSCenter($image, $text, $font, $size);
ImagePSText($image, $text, $font, $size, $white, $black, $x, $y);
ImagePSFreeFont($font); 

header('Content-type: image/png');
ImagePng($image);

ImageDestroy($image);

Unfortunately, this example doesn't work for GD's built-in fonts nor for TrueType fonts. There's no function to return the size of a string using the built-in fonts, and ImageTTFBBox( ) returns eight values instead of four. With a few modifications, however, we can accommodate these differences.

Because the built-in fonts are fixed-width, we can easily measure the size of a character to create a function that returns the size of the text based on its length. Table 15-1 isn't 100% accurate, but it should return results within one or two pixels, which should be good enough for most cases.

Table 15-1. GD Built-in font character sizes

Font number

Width

Height

1

5

6

2

6

8

3

7

13

4

8

15

5

9

15

Inside pc_ImageStringCenter( ) , we calculate the length of the string as an integral multiple based on its length; the height is just one character high. Note that ImageString( ) takes its y coordinate as the uppermost part of the text, so we should switch the sign back to a minus when you compute $y.

Here is an example using all five fonts that centers text horizontally:

$text = 'The quick brown fox jumps over the lazy dog.';
for ($font = 1, $y = 5; $font <= 5; $font++, $y += 20) {
    list($x, $y) = pc_ImageStringCenter($image, $text, $font);
    ImageString($image, $font, $x, $y, $text, $color);
}

The output is shown in Figure 15-8.

Figure 15-8. Centered GD built-in fonts
figs/phpc_1508.gif

For TrueType fonts, we need to use ImageTTFBBox( ) or the more modern ImageFtBBox( ). (The function with TTF in the name is for FreeType version 1.x; the one with Ft is for FreeType 2.x.) It returns eight numbers: the (x,y) coordinates of the four corners of the text starting in the lower left and moving around counter clockwise. So, the second two coordinates are for the lower right spot, and so on.

To make pc_ImageTTFCenter( ), begin with pc_ImagePSCenter( ) and swap this line:

    // find the size of the text 
    list($xl, $yl, $xr, $yr) = ImagePSBBox($text, $font, $size,
                                     $space, $tightness, $angle);

with these:

    // find the size of the text 
    $box = ImageTTFBBox($size, $angle, $font, $text);

    $xr = abs(max($box[2], $box[4]));
    $yr = abs(max($box[5], $box[7]));

Here's an example of pc_ImageTTFCenter() in use:

list($x, $y) = pc_ImageTTFCenter($image, $text, $font, $size);
ImageTTFText($image, $size, $angle, $x, $y, $white, $black,
             '/path/to/font.ttf', $text);

15.6.4 See Also

Recipe 15.6 for more on drawing text; Recipe 15.7 for more on centering text; documentation on ImageSX( ) at http://www.php.net/imagesx, ImageSY( ) at http://www.php.net/imagesy, ImagePSBBox( ) at http://www.php.net/imagepsbbox, ImageTTFBBox( ) at http://www.php.net/imagettfbbox, ImageFtBBox( ) at http://www.php.net/imageftbbox.

    Previous Section Next Section
    Index: [SYMBOL][A][B][C][D][E][F][G][H][I][J][K][L][M][N][O][P][Q][R][S][T][U][V][W][X][Z]


         Main Menu
    Main Page
    Table of content
    Copyright
    Preface
    Chapter 1. Strings
    Chapter 2. Numbers
    Chapter 3. Dates and Times
    Chapter 4. Arrays
    Chapter 5. Variables
    Chapter 6. Functions
    Chapter 7. Classes and Objects
    Chapter 8. Web Basics
    Chapter 9. Forms
    Chapter 10. Database Access
    Chapter 11. Web Automation
    Chapter 12. XML
    Chapter 13. Regular Expressions
    Chapter 14. Encryption and Security
    Chapter 15. Graphics
    15.1 Introduction
    Recipe 15.2 Drawing Lines, Rectangles, and Polygons
    Recipe 15.3 Drawing Arcs, Ellipses, and Circles
    Recipe 15.4 Drawing with Patterned Lines
    Recipe 15.5 Drawing Text
    Recipe 15.6 Drawing Centered Text
    Recipe 15.7 Building Dynamic Images
    Recipe 15.8 Getting and Setting a Transparent Color
    Recipe 15.9 Serving Images Securely
    Recipe 15.10 Program: Generating Bar Charts from Poll Results
    Chapter 16. Internationalization and Localization
    Chapter 17. Internet Services
    Chapter 18. Files
    Chapter 19. Directories
    Chapter 20. Client-Side PHP
    Chapter 21. PEAR
    Colophon
    Index


    More Books
    PHP Hacks
    Processing Xml With Java - A Guide To Sax, Dom, Jdom, Jaxp, And Trax
    The Koran (Holy Qur'an)
    Macromedia Flash 8 Bible
    Search Engine Optimization for Dummies
    YouTube Traffic
    PHP 5 for Dummies
    Harry Potter and The Chamber of Secrets
    Harry Potter and the Sorcerer's Stone
    The Pilgrim's Progress
    Wireless Hacks
    Flash Hacks. 100 Industrial-Strength Tips & Tools
    PayPal Hacks. 100 Industrial-Strength Tips and Tools
    Amazon Hacks
    Pdf Hacks
    The Da Vinci Code
    Google Hacks
    The Holy Bible
    Windows XP For Dummies
    Harry Potter and the Half-Blood Prince
    Seo Book
    Upgrading and Repairing Networks
    Macromedia Dreamweaver 8 UNLEASHED
    Windows XP Annoyances
    Windows XP Hacks
    Microsoft Windows XP Power Toolkit
    Teach Yourself MS Office In 24Hours
    iPod & iTunes Missing Manual
    PC Hacks 100 Industrial-Strength Tips and Tools
    PC Overclocking, Optimization, and Tuning - 2th Edition
    PC Hardware In A Nutshell 3rd Edition
    PC Hardware in a Nutshell, 2nd Edition
    Upgrading and Repairing PCs
    Google for Dummies
    MySQL Cookbook
    Teach Yourself Macromedia Flash 8 In 24 Hours
    PHP CookBook
    Sams Teach Yourself JavaScript in 24 Hours
    PHP5 Manual
    Free Games Paper Airplanes
    500 Juegos Gratis 500 Giochi Gratis 500 Jeux Gratuits 500 Jogos Gratis 500 Kostenlose Spiele