PHP Graphics Drawing Centered Text - Web Development and Design | Tutorial for Java, PHP, HTML, Javascript PHP Graphics Drawing Centered Text - Web Development and Design | Tutorial for Java, PHP, HTML, Javascript

Breaking

Post Top Ad

Post Top Ad

Sunday, June 23, 2019

PHP Graphics Drawing Centered Text

PHP Graphics


Drawing Centered Text

Problem

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

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 TrueType fonts, use the ImageFTCenter() function:

       function ImageFTCenter($image, $size, $angle, $font, $text, $extrainfo =
                                                       array()) {
              // find the size of the image
              $xi = ImageSX($image);
              $yi = ImageSY($image);

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

              $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) = ImageFTCenter($image, $size, $angle, $font, $text);
       ImageFTText($image, $size, $angle, $x, $y, $fore, $font, $text);

For built-in GD fonts, use the ImageStringCenter() function:

       function 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) = ImageStringCenter($image, $text, $font);
       ImageString($image, $font, $x, $y, $text, $fore);

Discussion

The two solution functions return the x and y coordinates for drawing. Depending on font type, size, and settings, the method used to compute these coordinates differs.

For TrueType fonts, pass ImageFTCenter() an image allocated from ImageCreateTrue Color() (or one of its friends) and a number of parameters to specify how to draw the text. Four parameters are required: the font size, the angle, text to be drawn, and the font. The final one is optional: the array of extra information that can be passed to ImageFTBBox().

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 ImageFTBBox(). It returns eight numbers: the (x,y) coordinates of the four corners of the text starting in the lower left and moving around counterclockwise. So the second two coordinates are for the lower-right spot, and so on. 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 values, you can now calculate the correct centering values. Because coordinates of the canvas have (0,0) in the upper-left corner, but ImageFTText() wants the lower-left corner, the formula for finding $x and $y isn’t the same. For $x, take the difference between the size of the canvas and the text. This gives the amount of white‐space that surrounds the text. Then divide that number by two to find the number of pixels you should leave to the left of the text. For $y, do the same, but add $yi and $yr. By adding these numbers, you 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.

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:

       list($x, $y) = ImageFTCenter($image, $size, $angle, $font, $text);
       ImageFTText($image, $size, $angle, $x, $y, $color, $font, $text);

Unfortunately, this example doesn’t work for GD’s built-in fonts or for TrueType fonts. There’s no function to return the size of a string using the built-in fonts. With a few modifications, however, you can accommodate these differences.

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

Table 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 ImageStringCenter(), 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 you should switch the sign back to a minus when you compute $y. 

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

       $w = 400; $h = 75;
       $image = ImageCreateTrueColor($w, $h);
       ImageFilledRectangle($image, 0, 0, $w-1, $h-1, 0xFFFFFF);

       $color = 0x000000; // black
       $text = 'Pack my box with five dozen liquor jugs.';

       for ($font = 1, $y = 5; $font <= 5; $font++, $y += 20) {
             list($x) = ImageStringCenter($image, $text, $font);
             ImageString($image, $font, $x, $y, $text, $color);
       }

The output is shown in Figure.
Figure Centered GD built-in fonts


No comments:

Post a Comment

Post Top Ad