Natürlich kann eine Grafikbibliothek und die dazugehörige Programmiersprache, in diesem Fall PHP, kein Grafikprogramm wie The GIMP oder Adobe Photoshop ersetzen. Viele automatisierte Effekte fehlen und die Programmierung von Grafiken ist auch nicht jedermanns Sache - vor allem Designer verzweifeln schnell. Dennoch, wenn es dynamisch sein soll, ist das Programmieren oder Ändern von Grafiken on-the-fly auf jeden Fall einen Blick wert.
Dieser Artikel zeigt viele interessante Beispiele und simuliert Effekte mit PHP, die Sie sicher auch aus Grafikprogrammen kennen.Installation
Die Installation der GD2 entnehmen Sie dem Artikel Neue Grafikwelt aus Ausgabe 2.03 des PHP Magazins. Geändert hat sich seit dem nur, dass in der Windows-Version die Erweiterung:extensions=php_gd2.dll
Buttons
Der Reiz einer dynamischen Navigation liegt darin, beliebig viele unterschiedlich beschriftete Navigationselemente per Skriptsprache zu generieren. Wenn es dann noch schön aussehen soll, benötigen Sie Grafiken dazu. Sie könnten die Grafiken natürlich komplett mit der GD2 erstellen. Allerdings ist dies etwas umständlich, da manche Elemente, wie abgerundete Rechtecke, Schatten oder ähnliches nicht vorhanden sind und sehr umständlich simuliert werden müssten. Als praxistauglicher erweist sich die Variante, einen Button in einem Grafikprogramm vorzuzeichnen und den Text dynamisch mittels der GD2 hinzuzufügen. Allerdings sind auch bei dieser Variante ein paar Klippen zu umschiffen, wenn Sie Buttons mit 256 Farben verwenden: Ein PNG mit 256 Farben belegt, wenn es mit imagecreatefrompng() geladen wird, schon alle 256 Farben in der Palette. Wenn Sie eine Beschriftung mit einer eigenen Farbe erstellen, findet diese Farben keinen Platz mehr in der Farbpalette. Auch die Funktion imagecolorresolve() hilft hier nicht viel. Sie verwendet immer die nächstgelegene Farbe, scheitert allerdings im folgenden Beispiel daran, dass kein Rotton im Bild vorhanden ist:<?phpheader("Content-type:image/png");$bild = imagecreatefrompng("button.png");$rot = imagecolorresolve($bild, 205, 0, 0);imagestring($bild, 5, 40, 15, "Produkte", $rot);imagepng($bild);imagedestroy($bild);?>
<?phpheader("Content-type:image/png");$bild_8bit = imagecreatefrompng("button.png");
$bild = imagecreatetruecolor(150, 50);$weiss = imagecolorallocate($bild, 255, 255, 255);imagefilledrectangle($bild, 0, 0, 150, 50, $weiss);
imagecopy($bild, $bild_8bit, 0, 0, 0, 0, 150, 50);
imagetruecolortopalette($bild, false, 250);
$rot = imagecolorallocate($bild, 205, 0, 0);imagestring($bild, 5, 40, 15, "Produkte", $rot);imagepng($bild);imagedestroy($bild);?>
$bild_8bit = imagecreatefrompng("button.png");$x = imagesx($bild_8bit);$y = imagesy($bild_8bit);$bild = imagecreatetruecolor($x, $y);$weiss = imagecolorallocate($bild, 255, 255, 255);imagefilledrectangle($bild, 0, 0, $x, $y, $weiss);imagecopy($bild, $bild_8bit, 0, 0, 0, 0, $x, $y);
Schwarz-Weiß
Die eben beschriebene Reduktion der Bildfarben mit imagetruecolortopalette() können Sie übrigens auch dazu verwenden, ein Farbpicture in eine reine Schwarz-Weiß-Grafik umzuwandeln. Die ersten Schritte kommen Ihnen sicherlich schon bekannt vor:<?phpheader("Content-type:image/png");$bild = imagecreatefromjpeg("glow.jpg");
imagetruecolortopalette($bild, true, 2);
$ind = imagecolorclosest($bild, 255, 255, 255);
imagecolorset($bild, $ind, 255, 255, 255);Nach derselben Methode färben Sie die dunklere Farbe in Schwarz und speichern das Bild zum Schluss als PNG:$ind_s = imagecolorclosest($bild, 0, 0, 0);imagecolorset($bild, $ind_s, 0, 0, 0);imagepng($bild);imagedestroy($bild);?>
Hintergrund transparent
Bei vielen Buttons und Navigationselementen ist der Hintergrund nicht transparent. Dies macht sich spätestens dann bemerkbar, wenn Sie den Button vor einen anderen Hintergrund legen möchten. Ein einfaches Beispiel illustriert dies: Eine HTML-Seite enthält eine per PHP generierte Grafik. Ändert sich nun die Hintergrundfarbe von Weiß auf Grün, erscheint der Button sehr störend.<body style="background-color:darkgreen"><img src="hintergrund.php" /></body>
$hinter = imagecolorresolve($bild, 255, 255, 255);imagecolortransparent($bild, $hinter);
Nichts ist wie vorher
Größere Änderungen an den Farben eines Bildes lassen sich am besten mit einer Schleife realisieren, die die einzelnen Farben durchlaufen. Dies ist allerdings nur bei einem Bild mit 8bit und einer Farbpalette wirklich einfach. Das folgende Beispiel zeigt, wie Sie ein 8bit-Bild in Graustufen umwandeln:$bild = imagecreatefrompng("button.png");for($i=0; $i<imagecolorstotal($bild); $i++) {$f = imagecolorsforindex($bild, $i);$gst = ($f["red"] + $f["green"] + $f["blue"]) / 3;imagecolorset( $bild, $i, $gst, $gst, $gst );}
$gst = $f["red"]*0.15 + $f["green"]*0.5 + $f["blue"]*0.35;
24bit-Bilder
Die Umwandlung von Farbwerten ist leider für 24bit-Bilder nicht so einfach, wie für ihre 8bit-Pendants. Bei der Graustufenumwandlung besteht der praktischste Weg darin, zuerst das Truecolor-Bild mit imagetruecolortopalette() in ein 8bit-Bild mit 256 Farben umzuwandeln. Dabei gehen allerdings Farbabstufungen verloren, da das Truecolor-Bild zuerst reduziert wird und erst anschließend die Graustufenumwandlung erfolgt. Um das Bild verlustfrei in Graustufen zu konvertieren, ist mehr Arbeit nötig: Sie müssen jedes einzelne Pixel des Bildes in seinen Graustufenwert umwandeln:<?phpheader("Content-type:image/jpeg");$bild = imagecreatefromjpeg("glow.jpg");Nach dem obligatorischen Start stellen Sie Breite und Höhe des Bildes fest und speichern sie in zwei Variablen:$x = imagesx($bild);$y = imagesy($bild);
for($i=0; $i<$y; $i++) {for($j=0; $j<$x; $j++) {//Anweisungen}}
$pos = imagecolorat($bild, $j, $i);
$f = imagecolorsforindex($bild, $pos);$gst = $f["red"]*0.15 + $f["green"]*0.5 + $f["blue"]*0.35;
$farbe = imagecolorresolve($bild, $gst, $gst, $gst);imagesetpixel($bild, $j, $i, $farbe);
Thumbnails
Umfangreiche Bildsammlungen finden Sie im Web oftmals in einer stark verkleinerten Variante. Diese kleinen Bilder oder auch Thumbnails (von engl. Daumennagel) lassen sich auch mit PHP dynamisch generieren. Das Bild, das verkleinert werden soll, ist die Quelle:$quelle = imagecreatefromjpeg("glow.jpg");$q_x = imagesx($quelle);$q_y = imagesy($quelle);
$z_x = round($q_x / 2);$z_y = round($q_y / 2);
$ziel = imagecreatetruecolor($z_x, $z_y);
imagecopyresampled($ziel, $quelle, 0, 0, 0, 0, $z_x, $z_y, $q_x, $q_y);
imagejpeg($ziel);imagedestroy($quelle);imagedestroy($ziel);
Zufall
Zum Abschluss erhält die Spielwiese der dynamischen Grafiken noch ein wenig Würze mit einem zufallsbasierten Bild. Listing 1 erzeugt ein Bild, das aus lauter Ellipsen besteht (fünfzig, um genau zu sein). Diese Ellipsen haben alle eine zufällige Größe und eine zufällige Farbe. Einzige Bedingung ist, dass keine Ellipse über den Rand des Bildes hinausragen darf. Eine Schleife erzeugt die Ellipsen. In der Schleife wird die Farbe mit den drei Farbwerten über eine Zufallszahl von 0 bis 255 zusammengesetzt. Die Koordinaten für den Mittelpunkt der Ellipse ($s_x und $s_y) sind ebenso von einer Zufallszahl abhängig, wie Breite und Höhe ($e_x, $e_y). Vier Fallunterscheidungen überprüfen, ob die Ellipse über die Grenzen des Bildes hinausragen würde. Ist dies der Fall, wird die Breite so angepasst, dass die Ellipse genau auf der Grenze endet. Zum Schluss verwendet imageellipse() die Angaben, um die Ellipse zu zeichnen (Listing 1).Listing 1<?phpheader("Content-type:image/png");$bild = imagecreatetruecolor(400, 400);$weiss = imagecolorallocate($bild, 255, 255, 255);imagefilledrectangle($bild, 0, 0, 400, 400, $weiss);$x = imagesx($bild);$y = imagesy($bild);mt_srand((double)microtime()*1000000);for ($i=0; $i<50; $i++) {$r = round(mt_rand(0, 255));$g = round(mt_rand(0, 255));$b = round(mt_rand(0, 255));$farbe = imagecolorresolve($bild, $r, $g, $b);$s_x = round(mt_rand(0, $x));$s_y = round(mt_rand(0, $y));$e_x = round(mt_rand(0, $x));$e_y = round(mt_rand(0, $y));if($s_x + $e_x / 2 > $x)$e_x = ($x - $s_x) * 2;if($s_x - $e_x / 2 < 0)$e_x = ($s_x) * 2;if($s_y + $e_y / 2 > $y)$e_y = ($y - $s_y) * 2;if($s_y - $e_y / 2 < 0)$e_y = ($s_y) * 2;imageellipse($bild, $s_x, $s_y, $e_x, $e_y, $farbe);}imagepng($bild);imagedestroy($bild);?>
Fazit
Bildmanipulationen begeistern Designer und Programmierer gleichermaßen. Die dynamischen Möglichkeiten der GD in Verbindung mit PHP wissen auch in den hier gezeigten Beispielen zu überzeugen. In der Praxis stellt sich immer die Frage, wie viel wirklich dynamisch gestaltet werden muss und wann das Grafikprogramm doch besser geeignet ist. Natürlich verkleinert ein Bildbearbeitungsprogramm Bilder sauberer, dafür entfällt bei der dynamischen Variante der zusätzliche Speicherplatz für die Thumbnails. Bildkorrekturen und Graustufenumwandlungen nimmt ein Webdesigner normalerweise in GIMP oder Photoshop vor, wenn eine Website allerdings kurzfristig oder zufallsbasiert Grau-in-Grau wirken soll, ist die dynamische Bildänderung schneller und pfiffiger. Gerade der Zufall eröffnet auch neue Möglichkeiten der Gestaltung. Ändern Sie doch einfach mal zufällig die Farbe Ihres Logos, so dass jeder Nutzer eine andere Optik sieht. Wer jetzt schimpft, das wären doch alles nur Spielereien, der hat zumindest bei per Zufall generierten Bildern Recht. Aber steckt nicht in jedem PHP-Programmierer, der freudig, wütend, verbissen und zum Schluss hoffentlich stolz an seinem Skript bastelt, ein kleines Spielkind? Tobias Hauser (th@hauser-wenz.de) ist Autor, Trainer und Berater in den Bereichen Web-Design und Web-Entwicklung. Als Speaker treffen Sie ihn auf nationalen und internationalen Konferenzen.Links und Literatur
- PHP Magazin 2.03, S.50




