| 
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.
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.
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.
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.
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
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.
|
 |