(PHP 4 >= 4.0.7, PHP 5)
imageftbbox — Give the bounding box of a text using fonts via freetype2
This function calculates and returns the bounding box in pixels for a FreeType text.
The font size. Depending on your version of GD, this should be specified as the pixel size (GD1) or point size (GD2).
Angle in degrees in which text will be measured.
The name of the TrueType font file (can be a URL). Depending on which version of the GD library that PHP is using, it may attempt to search for files that do not begin with a leading '/' by appending '.ttf' to the filename and searching along a library-defined font path.
The string to be measured.
Key | Type | Meaning |
---|---|---|
linespacing | float | Defines drawing linespacing |
imageftbbox() returns an array with 8 elements representing four points making the bounding box of the text:
0 | lower left corner, X position |
1 | lower left corner, Y position |
2 | lower right corner, X position |
3 | lower right corner, Y position |
4 | upper right corner, X position |
5 | upper right corner, Y position |
6 | upper left corner, X position |
7 | upper left corner, Y position |
The points are relative to the text regardless of the angle, so "upper left" means in the top left-hand corner seeing the text horizontally.
Beispiel #1 imageftbbox() example
<?php
// Create a 300x150 image
$im = imagecreatetruecolor(300, 150);
$black = imagecolorallocate($im, 0, 0, 0);
$white = imagecolorallocate($im, 255, 255, 255);
// Set the background to be white
imagefilledrectangle($im, 0, 0, 299, 299, $white);
// Path to our font file
$font = './arial.ttf';
// First we create our bounding box
$bbox = imageftbbox(10, 0, $font, 'The PHP Documentation Group');
// This is our cordinates for X and Y
$x = $bbox[0] + (imagesx($im) / 2) - ($bbox[4] / 2) - 5;
$y = $bbox[1] + (imagesy($im) / 2) - ($bbox[5] / 2) - 5;
imagefttext($im, 10, 0, $x, $y, $black, $font, 'The PHP Documentation Group');
// Output to browser
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>
Hinweis: Diese Funktion setzt die GD-Bibliothek in der Version 2.0.1 oder höher (empfohlen wird mindestens 2.0.28) voraus.
Hinweis: Diese Funktion ist nur verfügbar wenn PHP mit Freetype unterstützung (--with-freetype-dir=DIR ) kompiliert wurde
Version | Beschreibung |
---|---|
4.3.5 | extrainfo was made optional. |
For alignment i used this method:
if($align == "center" || $align == "right")
{
$verticaltxtspace = $backwidth - (2 * $posx);
$spacepositions = imagettfbbox($size, $angle, "fonts/verdanaz.ttf", " ");
$spacepx = $spacepositions[4] - $spacepositions[0];
// Split text in lines
$lines = split("[\r][\n]", $text);
for($count = 0; $count < count($lines); $count++)
{
$textpositions = imagettfbbox($size, $angle, "fonts/verdanaz.ttf", $lines[$count]);
$textpx = $textpositions[2] - $textpositions[0];
if($align == "right")
{
$spaces = ($verticaltxtspace - $textpx) / $spacepx;
}
else if($align == "center")
{
$spaces = (($verticaltxtspace - $textpx)/2) / $spacepx;
}
// Add spaces
$line = $lines[$count];
for($i = 0; $i < $spaces; $i++)
{
$line = " " . $line;
}
$lines[$count] = $line;
}
// Create new text of lines
$text = "";
for($count = 0; $count < count($lines); $count++)
{
$text .= $lines[$count] . "\r\n";
}
}
// Draw the shadow text on de shadow
imagettftext($background, $size, $angle, $posx, $posy, $textcolor, "fonts/verdanaz.ttf", $text);
ah... the problem between imageftbbox() and imagefttext() lies in the mirroring of the y-axes.
Below you see, for a font-size 16 the boudingboxes of "b", "p" and "bp":
< b: w=9 h=15
b(0,-1)
b(9,-1)
b(9,-16)
b(0,-16)
< p: w=9 h=16
p(0,4)
p(9,4)
p(9,-12)
p(0,-12)
< bp: w=20 h=20
bp(0,4)
bp(20,4)
bp(20,-16)
bp(0,-16)
If drawing "bp" using imagefttext() at y=0, the the top of "bp" indeed is at y=-16, and the bottom of "bp" at y=4. (Plus or minus a pixel here and there, because at y=0 there actually is a vissible pixel.)
IF we accept the idea that a bouding box is returned then:
$bbox= imageftbbox ( $size, $angle, $font, $txt);
$width = abs($bbox[4] - $bbox[0]);
$height = abs($bbox[1] - $bbox[5]);
may be a better kind of math. But it depends... You may want to subtract yet another '1' from both the width and the height.
But try drawing a "p" and next try a "d". Their bounding boxes differ 1 px in height. Of course the respective boxes, by imagefttext(), are placed at a different y coordinate. I noticed that if a "p" or a "b" is drawn at (0, 30) the first character of the string actually starts on, fills, the third horizontal pixel. Also: if your image is only 30 pixels in heigth, drawing text at (0, 30) means that the bottoms parts of "p", "q", "y" and alike are somewhere else...
imagettfbbox() returns an array with 8 elements representing four points making the bounding box of the text:
0 lower left corner, X position
1 lower left corner, Y position
2 lower right corner, X position
3 lower right corner, Y position
4 upper right corner, X position
5 upper right corner, Y position
6 upper left corner, X position
7 upper left corner, Y position
The points are relative to the text regardless of the angle, so "upper left" means in the top left-hand corner seeing the text horizontally.
ImageFTBBox returns a bounding box, not metrics, as some (most?) of the notes above seem to assume. The 8 values it returns specify the 4 corners of this bounding box. So to properly determine the width and height of a string you need to do:
$bbox = ImageFTBBox(...);
$width = abs($bbox[0]) + abs($bbox[2]); // distance from left to right
$height = abs($bbox[1]) + abs($bbox[5]); // distance from top to bottom
Here is a handy example I used to center "dynamic text" onto an image.
Ex. Say you want to center a clients IP Address onto a picture.
$ip=$_SERVER['REMOTE_ADDR'];
$details = imageftbbox($fontsize, 0, $font, $ip, array("linespacing" => 1));
$xcoord = ($imgwidth - $details[4]) / 2; // this will return the x coordinate centered to your specific image. Make sure you set $imgwidth to the width of the image you are using.
imagettftext($image, $fontsize, 0, $xcoord, $ycoord, $fontcolor, $font, $ip);
I noticed that PHP's True Type functions do not allow you to create text blocks with multiple lines that automatically adjust for alignment. I wrote a function that will allow you to generate images with multiple lines, control the alignment, and handle rotation. I hope it helps someone.
There was too much code to paste on this message post so you can grab it off of my webserver. I also created an example page so that you can see the code in action.
Example Page:
http://www.PrintsMadeEasy.com/code_samples/php/text_generation.php
Download the Text file:
http://www.PrintsMadeEasy.com /code_samples/php/text_generation.txt
i've found a work around for this situation
it seems that height is directly proportional to line spacing so you just have to apply the same factor to image height
for example :
$spacing = 0.7;
$params = array("linespacing" => $spacing);
$box = imageftbbox ($size, 0, $font, $text, $params);
$tw=$box[4]-$box[0]; //image width
$th=($box[1]-$box[5])*$spacing; //image height
This function can be used to generate right-aligned text. Just work out how wide the text image is and position it accordingly. Example:
$i_width = 200;
$i_height = 40;
$string = "Hello World!";
$pointsize = 10;
$fontfile = "/usr/local/lib/ttf/Helve.ttf";
$im = imagecreate($i_width, $i_height);
$black = imagecolorallocate ($im, 0, 0, 0);
$white = imagecolorallocate ($im, 255, 255, 255);
$string_size = ImageFtBbox($pointsize, 0, $fontfile, $string, array("linespacing" => 1));
$s_width = $string_size[4];
$s_height = $string_size[5];
ImageFtText($im, $pointsize, 0, $i_width - $s_width - 1, 0 - $s_height, $white, $fontfile, $string, array("linespacing" => 1));
Header ("Content-type: image/png");
ImagePNG ($im);
ImageDestroy ($im);