Werbung einblenden Werbung ausblenden


Home / Tutorials / PHP Handbuch / Bilder generieren mit PHP


Bilder on the fly, dynamisch Bilder generieren mit PHP
Die Funktion ImageColorAllocate
Die Funktion imageFilledRectangle
Die Funktion imagearc
Die Funktion imageline
Die Funktion imagepolygon
Die Funktion ImageString
Bilder verkleinern
Die Funktion copy
Die Funktion getimagesize
Die Funktion imagecreatefromjpeg
Die Funktion imagecopyresized

Bilder on the fly, dynamisch Bilder generieren mit PHP

Es gibt sehr viele Situationen, wo man entweder ein Bild neu generieren oder ein vorhandenes Bild modifizieren will. Ein Bild generieren will man z.B. wenn man statistische Daten graphisch aufbereiten will, siehe Charts generieren , Kurvenverläufe (z.B. Börsenkurse) optisch aufbereiten will, ästhetisch anspruchsvollere Counter haben will etc. etc. Das Bedürfnis, ein bestehendes Bild zu modifizieren, entsteht zum Beispiel, wenn man eine Anwendung hat, wo ein Bild upload möglich ist, siehe Formulareingaben auswerten/Bildupload, und von diesem Bild ein thumbnail generiert werden soll. Natürlich sind auch Anwendungen denkbar, wo ein Teil eines Bildes in einen anderes hineinkopiert werden soll, aus einem jpg-Bild ein png-Bild generiert werden soll, etc. etc. Um Grafiken mit PHP bearbeiten zu können, muss das GD Modul eingebunden sein. Man bindet das GD Modul ein, indem man in der php.ini, siehe PHP installieren, folgende Änderung durchführt. Man gehe zu der Stelle, wo die ganzen Extensions gelistet sind, man also sowas in der Art sieht.

;extension=php_fbsql.dll
;extension=php_fdf.dll
;extension=php_filepro.dll
;extension=php_gd.dll
;extension=php_gettext.dll
;extension=php_hyperwave.dll
;extension=php_iconv.dll
;extension=php_ifx.dll

Dort entfernt man dann das Semikolon vor php_gd.dll so dass die Zeile so aussieht.
extension=php_gd.dll

Dann läuft es. Allerdings sollte man beachten, dass der Funktionsumfang des gd-Moduls von der Version 1.6.6 auf die Version 2.2 drastisch erhöht wurde, das heisst die Version 2.2. bietet mehr fertige Funktionen. Hier werden nur die Funktionen der Version 1.6.6 dargestellt. Man beachte, dass die neueste Version des gd Moduls aufgrund von Copyright Problemen das gif- Format nicht mehr unterstützt. Statt dessen wird das png-Format unterstützt. Ein Bild kann man dann mit einem Skript dieser Art malen.

<?php
header ("Content-type: image/png");
$mein_bild = ImageCreate (300, 150);
$blau = ImageColorAllocate ($mein_bild, 21, 0, 177);
$gruen = ImageColorAllocate ($mein_bild, 50,148,0);
$rot = ImageColorAllocate ($mein_bild, 255,0,25);
$hellblau = ImageColorAllocate ($mein_bild,0,255,242);
imageFilledRectangle($mein_bild,20,20,280,130,$blau);
imagearc($mein_bild,150,75,50,50,0,360,$rot);
imageline($mein_bild,0,0,300,150,$hellblau);
imagedashedline($mein_bild,0,150,300,0,$hellblau);
$polygon_werte=array(20,130,50,110,70,90,90,50,110,100,120,150);
imagepolygon($mein_bild,$polygon_werte,6,$hellblau);
ImageString ($mein_bild, 10, 22, 5, "Was würde Picasso dazu sagen", $gruen);
ImagePNG ($mein_bild);
?>

Das Ergebnis:



Als erstes fällt auf, dass sich der HTTP Header geändert wurde. Da der Datenstrom, der ankommt, nicht mehr HTML ist, muss man dem Browser mitteilen, was
ankommt. In diesem Fall kommt ein Datenstrom vom Typ image an, genauer gesagt ein png-Bild.
Im Folgenden werden dem Bild Farben, Formen und Texte zugeordnet. Um aber einem Bild dies alles zuordnen zu können, muss man erstmal ein Bild
kreieren und einen Zeiger auf diesen Bild generieren. All dies macht die Funktion ImageCreate. Sie hat zwei Parameter, die Breite des
Bildes und die Höhe. Wer den oben stehenden Skript ausgelöst hat, hat festgestellt, dass unser Bild blau ist. Die naheliegende Frage, die
sich jetzt stellt, warum ist das Bild blau. Blau ist unser Bild, weil das die zuerst definierte Farbe ist. Mit dieser Farbe füllt das
Gd Modul das Bild aus. Unser Zeiger heißt $mein_bild. Anschliessend weisen wir
unserem Bild vier Farben zu, blau, grün, rot und hellblau.
$blau = ImageColorAllocate ($mein_bild, 21, 0, 177);

Die Funktion ImageColorAllocate

Die Funktion ImageColorAllocate hat vier Parameter. Den Zeiger auf das Bild und den rgb (rot, grün,blau) Wert für die Farbe. Wenn man zu einem bestimmten
Farbton den rgb Wert sucht, sollte man einfach ein Bildbearbeitungsprogramm aufmachen. Dort gibt es, zum Beispiel bei Ullead Photo Impact, eine Möglichkeit,
sich den rgb Wert zu jeder Farbe zeigen zu lassen. Anschliessend können wir beginnen, unserem Bild Figuren hinzuzufügen. Wir beginnen mit einem Rechteck.
imageFilledRectangle($mein_bild,20,20,280,130,$blau);

Die Funktion imageFilledRectangle

Die Funktion imageFilledRectangle generiert ein Rechteck, das mit der angegebenen Farbe gefült ist, in unserem Falle blau. Der zweite und der dritte Parameter
stehen hierbei für die linke, obere Ecke des Rechtecks. Dieser Punkt wird definiert als der Abstand von der linken, oberen Ecke des Bildes. Der zweite Parameter
ist hierbei der Abstand auf der x-Achse, der dritte Parameter ist der Abstand auf der y-Achse. Der vierte und der fünfte Parameter definieren nach dem
gleichen Schema die rechte, untere Ecke des Rechtecks.

Die Funktion imagearc

Mit der Funktion imagearc können wir unserem Bild einen Kreisbogen hinzufügen, oder eben auch einen
vollen Kreis.
imagearc($mein_bild,150,75,50,50,0,360,$rot);

Hierbei ist der zweite und der dritte Parameter das Zentrum des Bogens. Der vierte Paramter beschreibt die Höhe des Bogens, der fünfte die Breite. Der sechste Parameter
gibt an, wo der Bogen startet. Hierbei steht die Null für 15 Minuten. Der siebte Parameter gibt an, wieviel Grad der Bogen umspannen soll. Da wir einen Kreis zeichnen wollen,
geben wir 360 an. Der letzte Parameter ist selbserklärend. Es ist die Farbe. Während das Zeichnen eines Kreises also etwas kompliziert ist, ist das Zeichnen einer Linie
sehr einfach.

Die Funktion imageline

imageline($mein_bild,0,0,300,150,$hellblau);

Der erste und der letzte Parameter sind selbserklärend. Der zweite und der dritte Parameter gibt den Startpunkt der Linie an, der vierte und der fünfte den Endpunkt.
Die Funktion imagedashedline ist hinsichtlich der Parameterübergabe mit imageline identisch, allerdings generiert diese Funktion eine gestrichelte Linie.

Die Funktion imagepolygon

Einen Polygon, ein Vieleck, zeichnen wir mit der Funktion imagepolygon().
imagepolygon($mein_bild,$polygon_werte,6,$hellblau);

Der erste und der letzte Parameter sind auch hier wieder selbserklärend. $polygon_werte ist ein Array, der jeden Punkt des Polygons hält und zwar dergestalt, dass
immer zwei Elemente des Arrays den x und den dazugehörigen y Wert halten. $polygon_werte[0] ist also der x-Wert des ersten Punktes, $polygon_werte[1] ist der y-Wert
des ersten Punktes, $polygon_werte[3] is der x-Wert des zweiten Punktes, $polygon_werte[4] ist der y-Wert des zweiten Punktes etc.

Die Funktion ImageString

Mit der Funktion ImageString
können wir eine Zeichenkette in unser Bild einfügen.
ImageString ($mein_bild, 10, 22, 5, "Was würde Picasso dazu sagen", $gruen);

Der erste, fünfte und letzte Parameter sind selbsterklärend. Mit dem zweiten Parameter läßt sich die Größe der Schrift einstellen, mit dem dritten und vierten
den Startpunkt des Schriftzuges als x und y Wert.

Bilder verkleinern

Das ist wohl etwas, was man sich relativ häufig wünscht. Wer einen Anzeigenmarkt oder eine Auktion, ein Gästebuch oder ein Forum betreibt, der will in der Regel, dass von dem Bild, dass die User aus dem Browser heraus uploaden, siehe Formulareingaben auswerten/Bildupload, zuerst mal ein Thumbnail erscheint und erst wenn der User auf diesen clickt, erscheint das Bild in seiner vollen, ursprünglichen Größe, siehe Gästebuch. Einfach mit dem HTML Attribut width das Bild verkleinern, bringt nicht den gewünschten Effekt, weil das Bild dann zwar kleiner im Browser erscheint, aber immer noch die Orginalgröße mit der entsprechenden Anzahl an Bytes hat. Das führt dann zu relativ langen Ladezeiten. Im folgenden ein kleines Beispiel, das zeigt, wie man
Dateien, die aus dem Browser upgeloadet werden, verkleinert. Hierbei soll auf dem Zielrechner sowohl der generierte Thumbnail als auch das Orginalbild gespeichert werden. Das erste, was wir hierfür benötigen, ist ein HTML Formular, dass den Upload des Bildes ermöglicht. Das sieht dann so aus.

<html>
<head>
<title> Bild upload direkt aus dem Browser </title>
</head>
<form action=http://127.0.0.1/testbild.php enctype=multipart/form-data method=post>
Wählen Sie eine Datei
<input type=file name=datei>
<input type=submit value=hochladen>
</form>
</body>
</html>

Was es hierzu zu sagen gibt, wurde unter Formulareingaben auswerten/Bildupload bereits gesagt. Das
oben stehende HTML Formular ist unter irgendein_name.htm in der Document Root des HTTP Servers zu speichern. Der PHP Skript, der das upgeloadete Bild dann verkleinert sowie den Thumbnail und das Orginalbild abspeichert, sieht dann so aus.

<?
$dateiname=$HTTP_POST_FILES['datei']['name'];
copy($datei, "bilder/$dateiname");
$groesse=getimagesize("bilder/$dateiname");
$breite=$groesse[0];
$hoehe=$groesse[1];
$typ=$groesse[2];
print $typ;
$hoehe2=$hoehe*100/$breite;
$image1 = imagecreate(100,$hoehe2);
switch ($typ)
{
case 1:
$image = imagecreatefromgif("bilder/$dateiname");
break;
case 2:
$image = imagecreatefromjpeg("bilder/$dateiname");
break;
case 3:
$image = imagecreatefrompng("bilder/$dateiname");
break;
case 4:
$image = imagecreatefromwbmp("bilder/$dateiname");
break;
default: $gestorben="ja";
}
imagecopyresized($image1, $image, 0,0, 0,0,100,$hoehe2,$breite,$hoehe);

switch ($typ)
{
case 1:
imagegif($image1,"bilder/thumbs/$dateiname");
break;
case 2:
imagejpeg($image1,"bilder/thumbs/$dateiname",50);
break;
case 3:
imagepng($image1,"bilder/thumbs/$dateiname");
break;
case 4:
imagewbmp($image1,"bilder/thumbs/$dateiname");
break;
default: $gestorben="ja";
}
print "Das Bild wurde hochgeladen und abgespeichert.".
" Der Thumbnail ist im Ordner thumbs, das Bild in bilder";
?>

Der PHP Skript ist in der Document Root des HTTP Servers zu speichern unter dem Namen testbild.php. Innerhalb der Document Root des HTTP Servers benötigt man dann noch einen Ordner bilder und in diesem Ordner bilder wiederum einen Ordner thumbs. Wenn wir das Skript auslösen und ein Bild hochladen (bei neueren Versionen des Gd Moduls funktionnieren gif Bilder nicht !) haben wir das Orginal im Ordner bilder und den thumbnail im Ordner thumbs. Machen wir uns die Funktionsweise dieses Skriptes klar. Die Zeile

$dateiname=$HTTP_POST_FILES['datei']['name'];

wurde unter Formulareingaben auswerten/Bildupload bereits auführlich beschrieben. Sie erlaubt es uns,
auf recht einfache Weise den Namen des Bildes zu ermitteln. $datei ist dann, wie bereits beschrieben, der eigentliche Inhalt des Bildes.

Führen wir den Skript aus, erhalten wir im Ordner bilder das Orginalbild.



Und im Ordner bilder/thumbs einen Thumbnail dieses Bildes.



Aufbau des Skriptes

Die Funktion copy

Dieses Bild kopieren wir erstmal in den Ordner bilder.
copy($datei, "bilder/$dateiname");

Die Funktion getimagesize

Die Funktion getimagesize in

$groesse=getimagesize("bilder/$dateiname");

ermittelt mehr, als der Name vermuten lässt. Die Funktion getimagesize liefert einen Array, der die Breite, die Höhe und den Typ der Datei hält. Das dritte Element des Array hat den Wert 1 wenn es sich um ein gif Bild handelt, den Wert 2, wenn es sich um ein jpg Bild handelt, den Wert 3 wenn es sich um ein png Bild handelt und den Wert 4 wenn es eine swf Datei ist. Um das Bild proportional zu stauchen, müssen wir bei einer Breite, die wir vorgeben, die dazugehörige Höhe berechnen. Das machen wir mit einem Dreisatz.

$Hoehe_Ziel= $Hoehe_Quelle / $Breite_Quelle * $Breite_Ziel;

Das ergibt dann im Code diese Zeile

$hoehe2=$hoehe*100/$breite;

Dann kennen wir die Breite und die Höhe des zu produzierenden Bildes. Mit diesen Werten produzieren wir dann das Bild

$image1 = imagecreate(100,$hoehe2);

Wir haben jetzt einen Zeiger auf ein Bild. Wir brauchen aber, wie wir gleich sehen werden, auch einen Zeiger auf das Bild, von dem wir einen Thumbnail machen wollen. Dabei müssen wir unterscheiden, zwischen dem Bildtyp (gif, png, jpg). Wenn wir ein Bild neu generieren, ist der Type egal. Wenn wir aber einen Zeiger auf ein bereits existierendes Bild haben, ist der richtige Dateityp zu wählen. Folglich gibt es hier mehrere Funktionen, imagecreatefromgif, imagecreatefrompng etc. Der vollständigkeitshalber sei noch erwähnt, dass imagecreatefromgif aus den oben erwähnten Gründen nicht mehr unterstützt wird. Wer das also braucht, muss eine ältere Version des Gd Moduls einbauen.

Die Funktion imagecreatefromjpeg

Mit der Funktion
$image = imagecreatefromjpeg("bilder/$dateiname");

generieren wir einen Zeiger auf das ursprüngliche Bild. Für eine genaue Beschreibung der switch Anweisung siehe Bedingte Anweisungen. Damit haben wir, was wir brauchen. Einen Zeiger auf das Bild (in der richtigen Größe), wo der Thumbnail reinkommt und einen Zeiger auf das ursprüngliche Bild, also das Bild, dass da reinkopiert werden soll.

Die Funktion imagecopyresized

Mit der Funktion
imagecopyresized($image1, $image, 0,0, 0,0,100,$hoehe2,$breite,$hoehe);

übernehmen wir nun den gesamten Inhalt des ursprünglichen Bildes und kopieren ihn in das Thumbnail bild. Schauen wir uns die Parameter der Funktion im einzelnen
an.
$image1 =>Zeiger auf das Bild, in das wir den Thumbnail reinschiessen
$image =>Zeiger auf das ursprüngliche Bild
0,0 =>rechte, obere Ecke des Bereiches, der in das Thumbnail Bild eingefügt wird
0,0 =>rechte, obere Ecke des Bereiches,
den wir aus dem Orginalbild herausschneiden
100,$hoehe =>Angabe des Bereiches, den wir im Thumbnail zu nutzen gedenken (in unserem Beispiel die gesamte Fläche des Bildes)
$breite,$hoehe =>Angabe des Bereiches, den wir aus dem Orginalbild herausschneiden wollen (in unserem Beispiel den gesamten Bereich)

Wenn der Bereich, der herausgeschnitten wird, größer ist, als der Bereich, in den dieser Bereich dann eingefügt wird, wird der einzufügende Bereich gestaucht. Genau dies passiert hier. Umgekehrt umgekehrt. Wenn der Bereich, der herausgeschnitten wird, kleiner ist, als der Bereich, in den er eingefügt wird, wird er gestreckt.

vorhergehendes Kapitel