Centrowanie tekstu w PHP GD

9 02 2009

Ostatnio pracowałem z PHP GD. Zacząłem się zastanawiać, jak wycentrować tekst względem obrazka. Chciałem Wam dzisiaj przedstawić moje wnioski :)

Plan:
– Dzielimy szerokość obrazka na 2
– Obliczamy szerokość tekstu.
– Również dzielimy go na 2.
– Od podzielonej szerokości obrazka odejmujemy “połówkę” szerokości tekstu.
– Cieszymy się pozycją X tekstu :)
– Z Y podchodzimy podobnie:
– Do połowy wysokości obrazka dodajemy “połówkę” wysokości tekstu. (A dlaczego? Bo Y podawane do imagettftext to “baseline”, czyli dolna linia!)
Kod:
Skorzystamy z funkcji “imagettfbbox” aby obliczyć szerokość tekstu.
Funkcję, która będzie zwracać tablicę z pozycją [XY], w której powinniśmy wyświetlić tekst będzie się roboczo nazywać textCenter.
W parametrach będzie kolejno przyjmować:

$img – uchwyt naszego obrazka (stworzony np. funkcją imagecreate() )
$text – tekst, który chcemy wycentrować.
$size – wielkość czcionki.
$font – ścieżka do pliku z czcionką.

<?
function textCenter($img, $text, $size, $font) {
$t = imagettfbbox($size, 0, $font, $text);
$x = (imagesx($img)/2) - (($t[4] - $t[6])/2);
$y = (imagesy($img)/2) + (($t[1] - $t[7])/2);
return array("x" => round($x), "y" => round($y));
}
?>

Przykład użycia:

<?
/* Ustawiamy katalog czcionek na katalog skryptu.*/
putenv('GDFONTPATH=' . realpath('.'));
$img = imagecreatetruecolor(200,50);

/* Nasz tekst ;] */
$n = "Welcome!";

/* tu możesz podać nazwę jakiejkolwiek czcionki,
   która jest w katalog skryptu*/
$font = "MyUnderwood.ttf";

/* Wielkość czcionki */
$fontsize = 20;

/* Kolorek rushoFFy
 (zerżnięty z php.net:
http://pl.php.net/imagecreatetruecolor) ;] */
$text_color = imagecolorallocate($img, 233, 14, 91);

/* Nasza funkcja */
function textCenter($img, $text, $size, $font) {
$t = imagettfbbox($size, 0, $font, $text);
$x = (imagesx($img)/2) - (($t[4] - $t[6])/2);
$y = (imagesy($img)/2) + (($t[1] - $t[7])/2);
return array("x" => round($x), "y" => round($y));
}

$t = textCenter($img, $n, $fontsize, $font);
imagettftext($img, $fontsize, 0, $t['x'], $t['y'], $text_color, $font, $n);

/* Wyświetlamy obrazek */
header("Content-Type: image/png");
imagepng($img);
imagedestroy($img);
?>

Update 1: Dodane round przy zwracaniu wyniku w textCenter ;)
Update 2: Dopiero przed chwilą zauważyłem że oblicanie Y było zwalone ;)