Blog

Was mich so beschäftigt...


Textpositionen in GD mit imagefttext

Wenn man mit der GD-Lib von PHP ein Bild erstellen und darin Text platzieren möchte, ist die Dokumentation dazu nicht ganz eindeutig.

Ich diesem Beitrag erkläre ich die Verwendung von den Funktionen imagefttext und imageftbbox um Text pixelgenau in einem Bild platzieren zu können.

In meinem ersten Versuch habe ich mir die vorhandenen Funktionen kurz angeschaut, ein Beispiel kopiert und damit weitergemacht. Jedoch erschien der Text überhaupt nicht dort, wo ich ihn gerne gehabt hätte. Ich wollte den Text komplett zentriert in meinem Bild haben.

Wie jedes Programm verwendet aber GD auch eine eigene Methode um Komponenten auf einer Leinwand zu platzieren.

Bei Gimp zum Beispiel ist der Nullpunkt des Koordinatensystems links oben. Bei Inkscape dagegen links unten. GD platziert den Nullpunkt wie Gimp links oben.

Als Hintergrund habe ich mit Gimp kurz ein Bild mit einigen Linien erstellt.

Rasterbild in Gimp

Die Methode imagettftext um Text zu platzieren erwartet einfach eine X/Y Koordinate, welche die linke obere Ecke des Textes markiert.

Um dies aber korrekt setzen zu können muss ich aber wissen, wie hoch und breit der Text werden wird.

Dazu bietet GD eine andere Methode imagettfbbox, welche die Boundingbox eines bestimmten Textes zurück.

Diese Methode gibt ein Array zurück mit acht Werten. Jeweils zwei Werte geben zusammen die Koordinaten für alle vier Ecken der Bounding Box an.

Koordinaten der Bounding Box

Je nach verwendeter Schriftart unterscheiden sich diese Koordinaten natürlich sehr. Obiges Beispiel verwendet eine Handschrift Pinyon Script.

Platzierter Text mit Pinyon Script

Wenn ich Beispielsweise Oswald verwende, gibt die Funktion ganz andere Koordinaten zurück.

Koordinaten der Bounding Box

Platzierter Text mit Oswald

Spannend ist insbesondere, dass die Koordinaten teils negative Werte enthalten. Der Nullpunkt dieser Methode ist nämlich nicht die linke untere Ecke, sondern der linke Startpunkt auf der Basislinie des Texts. Das heisst, je nach Schriftart können sich Teile des Buchstabens weiter links befinden (wie im Beispiel mit Pinyon Script) oder auch darunter wie bei Buchstaben mit Unterlänge (g, q und p).

Um die Bounding Box zu bekommen habe ich folgenden Code geschrieben

$bbox   = imageftbbox( $fontsize, 0, $fontpath, $text );
$width = abs( $bbox[0] ) + abs( $bbox[4] );
$height = abs( $bbox[5] ) + abs( $bbox[1] );

Ich verwende jeweils die abs-Methode um negative in positive Zahlen umzuwandeln.

So habe ich die beiden Offset-Werte genommen

$xoffset = abs( $bbox[0] );
$yoffset = abs( $bbox[7] );

um dann später der Koordinate hinzuzufügen

$x = $imagecenter['x'] - $width/2;
imagefttext( $im, $fontsize, 0, $x + $xoffset, $y + $yoffset, $color, $fontpath, $text );

die X-Koordinate berechne ich, indem ich zuerst den Bildmittelpunkt berechnet habe (Breite des Bildes geteilt durch zwei) und davon die Hälfte der Bounding-Box abziehe.

Damit habe ich wie in beiden obigen Beispielen erreicht, dass der Text in der Mitte des Bildes erscheint.

Diese Lösung ist zwar nicht perfekt, für meinen Zweck aber ausreichend. Werden zum Beispiel Buchstaben mit Unterlänge verwendet, springt der Text etwas nach oben, da die Bounding Box etwas grösser wird. Theoretisch korrekt also, aber nicht immer so gewünscht, da die Basislinie des Textes dann an einem anderen Ort liegt.

Veröffentlicht am 23.10.2018