Derzeit online: ca. 93 User  
Spenden via PayPal Wie wäre es mit einem PHP-Buch zu Weihnachten? PHP für dich ist auch als Buch erhältlich - im handlichen Format, zum Nachschlagen, Mitnehmen oder gemütlichen nebenbei Lesen. Mit noch mehr Informationen, zusätzlichen Beispielen und Übungsaufgaben.
Jetzt in der aktualisierten Version bei Amazon oder BoD bestellen!


Schnipsel

PHP - Eine brennende Kerze mit gd-lib erzeugen

Winterzeit, Kerzenzeit. Warum nicht einmal eine brennende Kerze mit PHP erstellen? Dank gd-lib ist das gar keine große Sache.

Zunächst brauchen wir eine png-Grafik mit einer Kerzenflamme. Wir verwenden png, weil es transparente Flächen ermöglicht und wir somit später eine beliebige Hintergrundfarbe wählen können. Wenn dir das nicht wichtig ist, kannst du natürlich auch mit einer jpg-Datei arbeiten, brauchst dann aber später andere Befehle. Erstelle dir jetzt entweder eine eigene Flamme, oder verwende einfach meine, indem du sie dir hinunter lädst:

Kerzenflamme

Als nächstes brauchen wir eine PHP-Datei. Wir werden die Datei am Ende so schreiben, dass die Datei selbst unser Bild ergibt. Da das allerdings den Nachteil hat, dass wir keine Fehlermeldungen angezeigt bekommen, lassen wir das Bild zunächst in eine Datei schreiben und anzeigen und ändern das erst am Ende.

Wir beginnen also zunächst damit, die Breite und Höhe des späteren Bildes in eine Variable zu schreiben und dann daraus ein leeres Bild zu erzeugen und in eine Datei zu schreiben. Dieses Bild lassen wir uns dann auch gleich anzeigen.
<?php
$breite = 150;
$hoehe = 300;
$kerze = imagecreatetruecolor($breite, $hoehe);
imagepng($kerze, "kerze.png");
?>
<img src="kerze.png" alt="Kerze" />
Mit imagecreatetruecolor($breite, $hoehe) erstellen wir ein Bild mit der von uns festgelegten Breite von 150 und einer Höhe von 300 Pixeln. Wir speichern die Informationen zu dem Bild in der Variable kerze und können damit später jederzeit das Bild ansprechen. Um das Bild als png zu speichern verwenden wir am Ende den Befehl imagepng($kerze, "kerze.png"). Der erste Wert in der Klammer ist die Variable in der unser Bild gespeichert wurde, der zweite Wert ist der Dateiname. Er muss in Anführungszeichen gesetzt werden (oder als Variable übergeben werden). Es kann passieren, dass du die Zugriffsberechtigungen für das Verzeichnis, in dem die Datei später liegen soll, ändern musst. Am Schluss geben wir einfach im HTML-Code an, dass das Bild angezeigt werden soll. Bisher sieht es alledings nur so aus:

Kerze

Eine große schwarze Fläche ist natürlich nicht das, was wir uns vorstellen, also färben wir zunächst den Hintergrund ein. Ich verwende in diesem Beispiel als Hintergrundfarbe ein helles Grau, du kannst aber natürlich auch andere Farben wählen. Wir ergänzen den Code zwischen imagecreatetruecolor und imagepng, so dass er dann so aussieht:
<?php
$breite = 150;
$hoehe = 300;
$kerze = imagecreatetruecolor($breite, $hoehe);
<b>$hintergrundfarbe = imagecolorallocate($kerze, 200, 200, 200);
imagefill($kerze, 0, 0, $hintergrundfarbe);</b>
imagepng($kerze, "kerze.png");
?>
<img src="kerze.png" alt="Kerze" />
Was passiert hier?

Zuerst legen wir eine Farbe für den Hintergrund fest. Wir nennen die Variable hintergrundfarbe und verwenden die Anweisung imagecolorallocate($kerze, 200, 200, 200), um die Farbe darin zu speichern. imagecolorallocate braucht dafür zunächst das Bild, in dem die Farbe angewendet werden soll - in unserem Fall also das in der Variable kerze gespeicherte - und danach die Farbangaben. Diese Farbangaben sind in RGB, also Rot-, Blau- und Grünwerte. Nimmt man bei allen drei Werten 255, so erhält man weiß. Alle Werte auf 0 wäre schwarz. Im Normalfall kann dir ein Grafikprogramm diese Werte anzeigen.

Nachdem die Farbe jetzt verfügbar ist, können wir das Bild damit füllen. Dafür gibt es die Funktion imagefill. Auch hier müssen wir zuerst das Bild angeben, das gefüllt werden soll. Danach geben wir die Koordinaten an, ab denen die Füllfarbe aufgetragen werden soll. Die erste Angabe ist die x-Koordinate, die zweite die y-Koordinate. Unsere Angabe 0, 0 ergibt also links oben. Als letzten Wert übergeben wir die gewünschte Farbe, die bei uns in der Variable hintergrundfarbe gespeichert ist.

Jetzt haben wir zwar immer noch nur eine leere Fläche, aber zumindest ist die Hintergrundfarbe schon die von uns gewünschte:

Kerze

Der nächste Schritt besteht darin, dass wir festlegen, wie breit unsere Kerze sein soll und diesen Wert in einer Variable abspeichern. Außerdem legen wir mit imagecolorallocate eine Farbe für unsere Kerze fest. Ich nehme dafür einen lila Farbton. Die Angaben müssen vor imagepng($kerze, "kerze.png") erfolgen.
$kerzendicke = 100;
$kerzenfarbe = imagecolorallocate($kerze, 160, 119, 191);
Als nächstes wollen wir die Kerze in das Bild einfügen. Dafür werden wir einfach ein Rechteck in der gewünschten Farbe ins Bild setzen. Die Funktion dafür nennt sich imagefilledrectangle und benötigt von uns genaue Koordinatenangaben, wo das Rechteck gezeichnet werden soll. Aus diesem Grund berechnen wir zunächst diese Koordinaten.
$kerze_x1 = ($breite - $kerzendicke) / 2;
$kerze_y1 = 80;
$kerze_x2 = $kerze_x1 + $kerzendicke;
$kerze_y2 = $hoehe - $kerze_x1;
Das sieht jetzt erstmal unheimlich kompliziert aus, ist es aber eigentlich gar nicht. Wir gehen es einfach Schritt für Schritt gemeinsam durch:

Die ersten zwei Variablen kerze_x1 und kerze_y2 werden später angeben, wo die obere, linke Ecke unserer Kerze ist. Die zweiten zwei Variablen ergeben dann die untere, rechte Ecke.

kerze_x1: Da die Kerze nicht links ins Eck gequetscht sein soll, verwenden wir einen Rand rund um die Kerze herum. Die Breite dieses Randes ergibt sich aus der gesamten Bildbreite - in der Variable breite gespeichert - abzüglich der Kerzendicke, die in der Variable kerzendicke gespeichert ist. Da wir links und rechts gleich viel Randfläche haben wollen, dividieren wir diesen Wert noch durch zwei.
kerze_y1: Die Kerze soll nicht am obersten Bildrand beginnen, sondern ein Stück weiter unten. Ich nehme bis auf weiteres hier einfach 80 Pixel als Wert, da ich weiß, dass die Kerzenflamme 60 Pixel hoch ist und ich somit noch etwas Puffer haben werde.
kerze_x2: Diesen Wert berechnen wir einfach aus der ersten x-Koordinate und der gewünschten Kerzendicke, indem wir die beiden Werte addieren.
kerze_y2: Für diesen Wert, der angibt, wie weit die Kerze nach unten geht, könnten wir einfach die Bildhöhe verwenden. Da wir aber schon links und rechts der Kerze einen schönen Rand haben, wollen wir den gleichen Rand auch für unten verwenden und ziehen daher von der festgelegten Bildhöhe die Variable kerze_x1 ab, da dieser Wert der Randbreite entspricht.

Nachdem wir all diese Koordinaten berechnet haben, können wir als nächstes unser Rechteck zeichnen:
imagefilledrectangle($kerze, $kerze_x1, $kerze_y1, $kerze_x2, $kerze_y2, $kerzenfarbe);
Ich vermute, dir ist jetzt schon klar, was die ganzen Angaben bei imagefilledrectangle bewirken, oder?

Der erste Wert ist unser Bild. Danach folgen die vier Angaben für die Koordinaten, wobei die ersten zwei Werte die x- und y-Koordinaten für den Startpunkt und die nächsten zwei Werte die Angaben für den Endpunkt sind. Als letztes geben wir unsere vorher festgelegte Farbe an und das ganze sieht dann so aus:

Kerze

So ganz nach Kerze sieht es immer noch nicht aus, daher kümmern wir uns als nächstes um einen Docht.

Auch der Docht besteht aus einem einfachen Rechteck, das wir schwarz färben. Wir müssen also zunächst die Farbe schwarz festlegen.
$schwarz = imagecolorallocate($kerze, 0, 0, 0);
Danach brauchen wir wieder ein wenig Rechnerei, um die richtigen Koordinaten für unseren Docht herauszufinden:
$docht_x1 = $kerze_x1 + ($kerzendicke / 2) - 1;
$docht_y1 = $kerze_y1 - 13;
imagefilledrectangle($kerze, $docht_x1, $docht_y1, $docht_x1+2, $docht_y1+10, $schwarz);
Dieses Mal legen wir nur die Variablen für die Anfangskoordinaten fest und ich zeige euch, dass man auch direkt beim Aufruf der Funktion imagefilledrectangle Berechnungen durchführen kann.

Den x1-Wert für den Docht berechnen wir anhand des horizontalen Beginns der Kerze - also der Position kerze_x1, sowie der Hälfte der Kerzendicke, damit er auch in der Mitte der Kerze steht. Zusätzlich ziehen wir ein weiteres Pixel ab, weil unser Docht insgesamt 2 Pixel breit sein soll. Damit er exakt zentriert ist, muss er also ein Pixel weiter links als die eigentliche Mitte ist, anfangen.

Der y1-Wert ergibt sich aus der vertikalen Startposition der Kerze, abzüglich 13 Pixel. Diese 13 Pixel setzen sich aus 10 Pixel, die wir als Dochthöhe verwenden werden und einem Abstand von 3 Pixeln zwischen Docht und Kerze zusammen. Man kann Docht und Kerze natürlich auch aneinander stoßen lassen, dann verwendet man eben nur die gewünschte Dochthöhe als Abzug.

Als nächstes ziehen wir mit imagefilledrectangle unser Rechteck auf. Die ersten drei Angaben kennst du schon: Das Bild und die Startpunkte des Dochtes. Da wir die Endpunkte dieses Mal nicht in Variablen gespeichert habe, schreiben wir diese kleinen Berechnungen direkt als Werte in die Funktion. Für den 2. x-Wert verwenden wir docht_x1+2, also den Beginn des Dochtes plus 2 Pixel, die er breit sein soll. Genauso funktioniert auch die Berechnung des 2. y-Wertes, nur das wir hier von docht_y1 ausgehen und 10 Pixel hinzuaddieren, die der Docht ja hoch sein sollte.

Jetzt sollte es so aussehen - ist doch schon fast eine Kerze, oder?

Kerze

Natürlich soll unsere Kerze auch noch brennen und nicht nur ausgeblasen sein und so kommt jetzt unsere Flamme ins Spiel. Speichere sie an der gleichen Stelle, wie auch deine PHP-Datei (oder passe den Pfad entsprechend an). Wir kopieren jetzt diese Flamme in unser Bild. Dazu müssen wir zuerst die Flamme in einer Variable abspeichern:
$flamme = imagecreatefrompng("flamme.png");
Über imagecreatefrompng("Dateiname") rufen wir unsere Flammengrafik auf. Wenn deine Flamme nicht als png-Datei vorliegt, musst du eine andere Funktion aufrufen - z. B. imagecreatefromjpeg für jpg-Dateien. In der Klammer gibst du den Dateinamen in Anführungszeichen an.

Um die Flamme jetzt ins Bild zu bekommen, müssen wir auch an dieser Stelle wieder die notwendigen Koordinaten berechnen.
$flamme_x1 = $kerze_x1 + ($kerzendicke / 2) - 13;
$flamme_y1 = $kerze_y1 - 62;
imagecopy($kerze, $flamme, $flamme_x1, $flamme_y1, 0, 0, 26, 60);
flamme_x1 ergibt sich - ähnlich wie der Docht - aus dem horizontalen Startpunkt der Kerze plus der Hälfte der Kerzendicke. Dieses Mal ziehen wir davon aber nicht nur ein Pixel ab, sondern 13. Auf die 13 kommen wir durch die Breite der Flammengrafik. Diese beträgt 26 Pixel. Die Hälfte davon ist dann unsere 13.

Auch flamme_y1 wird ähnlich wie der Docht berechnet. Die 62 entsteht durch eine Höhe des Ausgangsbildes von 60 Pixel, und weiteren 2 Pixel, die ich als Abstand zur Kerze haben möchte.

Um das anschaulicher darzustellen, zeige ich in diesem Beispiel, wie es aussehen würde, wenn die Breite und die Höhe der Flamme in einer Variable gespeichert wäre:
$flammenbreite = 26;
$flammenhoehe = 60;
$flamme_x1 = $kerze_x1 + ($kerzendicke / 2) - ($flammenbreite / 2);
$flamme_y1 = $kerze_y1 - $flammenhoehe - 2;
Ich bevorzuge im Normalfall die zweite Variante, da sie flexibler ist. Welche du nimmst, bleibt aber selbstverständlich dir überlassen.

Was wir jetzt noch immer nicht haben, ist die Flamme im Bild. Dafür gibt es die Funktion imagecopy.
imagecopy($kerze, $flamme, $flamme_x1, $flamme_y1, 0, 0, $flammenbreite, $flammenhoehe);
Hier geben wir zunächst wie gewohnt die Variable kerze an, in der unser gesamtes Bild gespeichert ist. Die zweite Angabe ist die Variable, in der wir die Grafik gespeichert haben, die in unser Bild hinein kopiert werden soll. Bei uns ist das also die Variable flamme. Die nächsten zwei Angaben sind die x- und y-Koordinaten, an die das Bild kopiert werden soll. Die zwei darauf folgenden Werte geben an, wo im zu kopierenden Bild, der Kopiervorgang starten soll. Da wir das gesamte Flammenbild kopieren wollen, geben wir also einfach 0, 0 an, um links oben zu beginnen. Die letzten zwei Werte geben an, wieviel kopierte werden soll. Zuerst die Breite und dann die Höhe. Da wir immer noch das gesamte Bild haben wollen, geben wir hier unsere zwei Variablen flammenbreite und flammenhoehe wieder an. Wenn wir die Werte nicht in Variablen gespeichert haben, können wir natürlich auch direkt die Zahlen hinschreiben.

Und schon haben wir eine richtige, brennende Kerze:

Kerze

Was wir jetzt noch ändern wollen ist die Speicherung des Bildes. Bisher speichern wir am Ende unser Bild als png-Datei auf dem Server. Eigentlich wollen wir aber einfach die PHP-Datei als Grafik aufrufen können. Dazu benötigen wir eine Header-Angabe in der Datei. Diese muss ganz am Anfang erfolgen und es darf keinerlei Text etc. ausgegeben werden - ein jeder echo-Befehl oder jede Fehlermeldung, würde also unser Bild dazu bringen, nicht zu funktionieren.

Für eine png-Datei verwenden wir die Header-Angabe Header("Content-Type: image/png").
Header("Content-Type: image/png");
Auch am Ende unserer Datei müssen wir noch etwas verändern. Zunächst muss der HTML-Code zur Anzeige des Bildes entfernt werden, da dieser eine Ausgabe darstellen würde. Außerdem müssen wir PHP anweisen, das Bild nicht länger in einer Datei zu speichern, sondern es nur in ein png umzuwandeln. Dafür ändern wir die Angaben bei imagepng.
imagepng($kerze);
Wir geben also einfach keinen Dateinamen mehr an und lassen den kompletten zweiten Wert weg. Jetzt kann das Bild in jeder beliebigen Datei über den normalen HTML-Code img aufgerufen werden. Als Datei gibt man dann die PHP-Datei an, also z. B.
<img src="kerze.php" />
Der gesamte Code sieht jetzt so aus (mit Zeilennummern dieses Mal - diese gehören nicht zum eigentlichen Code):
  1. <?php
  2. Header("Content-Type: image/png");
  3. $breite = 150;
  4. $hoehe = 300;
  5. $kerze = imagecreatetruecolor($breite, $hoehe);
  6. $hintergrundfarbe = imagecolorallocate($kerze, 200, 200, 200);
  7. imagefill($kerze, 0, 0, $hintergrundfarbe);
  8. $kerzendicke = 100;
  9. $kerzenfarbe = imagecolorallocate($kerze, 160, 119, 191);
  10. $kerze_x1 = ($breite - $kerzendicke) / 2;
  11. $kerze_y1 = 80;
  12. $kerze_x2 = $kerze_x1 + $kerzendicke;
  13. $kerze_y2 = $hoehe - $kerze_x1;
  14. imagefilledrectangle($kerze, $kerze_x1, $kerze_y1, $kerze_x2, $kerze_y2, $kerzenfarbe);
  15. $schwarz = imagecolorallocate($kerze, 0, 0, 0);
  16. $docht_x1 = $kerze_x1 + ($kerzendicke / 2) - 1;
  17. $docht_y1 = $kerze_y1 - 13;
  18. imagefilledrectangle($kerze, $docht_x1, $docht_y1, $docht_x1+2, $docht_y1+10, $schwarz);
  19. $flamme = imagecreatefrompng("media/flamme.png");
  20. $flammenbreite = 26;
  21. $flammenhoehe = 60;
  22. $flamme_x1 = $kerze_x1 + ($kerzendicke / 2) - ($flammenbreite / 2);
  23. $flamme_y1 = $kerze_y1 - $flammenhoehe - 2;
  24. imagecopy($kerze, $flamme, $flamme_x1, $flamme_y1, 0, 0, $flammenbreite, $flammenhoehe);
  25. imagepng($kerze);
  26. ?>
Und im zweiten Teil verrate ich euch, wie man die Kerze dazu bringt, hinunter zu brennen.

Autor: Claudia Unkelbach
© 2001 - 2014 Claudia Unkelbach
Gießener Straße 75, 35396 Gießen