Grafikfunktionen - Grundlagen

Ja, PHP kann so ziemlich alles, auch Grafiken während der Laufzeit verarbeiten. Man kann einfache Grafiken selbst kreieren, aber vor allem häufig in größeren Seiten benötigte Extras wie Miniaturansichten von Bildern oder eine Bildgröße automatisch, dynamisch, und noch während dem Hochlade-Vorgang erzwingen.

PHP kann das aber nicht von sich aus, es bietet nur eine Schnittstelle zur Grafik-Bibliothek "GD" an. Die Unterstützung dieser, muss in der Installation von PHP aktiviert werden. So ziemlich jeder große Speicher-Anbieter bietet das heutzutage standardmäßig an.

Hintergrund
Grafiken werden von PHP/GD als so genannte Bild-Ströme erzeugt. Einen Bild-Strom kann man als Ergebnis einer Funktion ganz normal in einer Variabel ablegen. Beim erstellen eines neuen Bildstroms, muss man sich bereits für ein Dateiformat entscheiden. Die neuesten Versionen der GD ermöglichen einem das Verarbeiten von JPEG und PNG Grafiken. Die Unterstützung von GIF-Grafiken wurde ab Version 1.6 aus der GD entfernt.

Bild-Strom erzeugen
Für das Erstellen neuer Bildströme gibt es die beiden Funktionen ImageCreate und ImageCreateTrueColor. Der Unterschied zwischen den beiden liegt, wie der Name der zweiten Funktion erkennen lässt, in der Anzahl der verfügbaren Farben. ImageCreate erstellt ein Bild mit 256 Farben, ImageCreateTrueColor dagegen erstellt ein 32bit Farbbild, das bedeuet 24bit für 16,7 Millionen Farben und 8bit für Transparenz (= Graustufen & Alpha-Kanal).

GIF unterstützt TrueColor nicht. Daher sind GIF-Bilder auch von minderwertiger Qualität, sie können nur 256 Farben darstellen und nur zwischen Farbe und totaler Transparenz unterscheiden, während TrueColor mit seinem AlphaKanal Abstfungen ermöglicht, die beispielsweise die wunderschönen Schlagschatten bei PNG-Grafiken ermöglichen. (PNG ist das zurzeit fortschrittlichste, verfügbare Bildformat - bringts aber selbst bei voller Kompression auf ordentliche Dateigrößen). Kleiner Ätz am Rande: Windows verwendet - wie immer hinten nach - GIF. Linux verwendet PNG (Ratet mal wo die GUIs schöner sind ;-)

Erstellen wir nun einen Bild-Strom und speichern in in der Variabel $bild:
<?php
$bild = ImageCreate(400,300); //256 Farben
?>

<?php
$bild = ImageCreateTrueColor(400,300); //32bit
?>
?>


Damit eröffnen wir einen Bild-Strom für ein Bild von 400 Pixel Breite und 300 Pixel Höhe. Rufst du nun das PHP-Skript auf, kriegst du lediglich eine blanke Seite zu sehen. Das liegt daran, das du nur einen Strom erstellt hast. Dieser ist lediglich ein theoretisches Konstrukt mit dem wir weiterarbeiten müssen, darstellen kann man den Strom nicht, wozu auch, es wäre eine Grafik ohne Inhalt.

Bild-Strom ausgeben
Um einen Strom letztendlich als Grafik darzustellen, müssen wir ihn mit einer der drei Image* Funktionen ausgeben. Je nachdem welches Grafik-Format benötigt wird, bzw. verfügbar ist: ImageGIF, ImageJPEG, ImagePNG. Ein mit ImageCreateTrueColor erzeugter Bild-Strom kann nciht als GIF ausgegeben werden, dieses kann ja nur 256 Farben darstellen, ImageCreateTrueColor liefert jedoch 32bit. Unser Strom heißt nun $bild, folglich geben wir ihn auch aus:
<?php
$bild = ImageCreateTrueColor(400,300); //32bit Farben
ImagePNG($bild); // Als PNG
?>
<?php
$bild = ImageCreateTrueColor(400,300); //32bit Farben
ImageJPEG($bild); // Als JPEG
?>
<?php
$bild = ImageCreate(400,300); //256 Farben
ImageGIF($bild); // Als GIF (Achtung! Kein TrueColor!)
?>


Wenn du das Skript jetzt aufrufst, zeigt er dir ein Wirrwar irgendwelcher Zeichen an. Das liegt daran, das dein PHP-Skript als Text-Datei erkannt wird. Der Quelltext, den PHP jetzt zurückliefert, muss jedoch nicht als Text, sondern als Grafik interpretiert werden. Damit das Programm, mit dem du das Skript aufgerufen hast, dies nun versteht - denn mit der Annahme das die PHP-Datei ihm Text liefert, liegt es sonst auch richtig - musst du ihm noch zusätzlich einen HTTP-Auszeichner mitgeben, der dem Programm signalisiert: "Halt! Diesmal nicht Text sondern Grafik!".

Solch einen Auszeichner, liefert die Funktion "header". Das HTTP (jenes Protokoll das festlegt wie die Programme im Internet Text darstellen sollen) schreibt eine sehr genaue Syntax vor, die du unbedingt einhalten musst, damit dein Netz-Klient versteht, dass du im da eine Grafik generiert hast. Diese ist aber denkbar einfach, du sagst einfach das der Inhalt (zu engl. Content) vom Typ "Grafik" ist, und sagst dann noch welches Grafik-Format. Der Auszeichner muss unbedingt zuallererst im Skript stehen! Er heißt ja "Header" also wie "Kopf", im Sinne von "ganz oben".
<?php
header('Content-type: Image/PNG');
$bild = ImageCreateTrueColor(400,300); //32bit Farben
ImagePNG($bild);
ImageDestroy($bild);
?>

<?php
header('Content-type: Image/JPEG');
$bild = ImageCreateTrueColor(400,300); //32bit Farben
ImageJPEG($bild);
ImageDestroy($bild);
?>


Die beiden Skripta oben liefern uns jetzt ein 400 Pixel breites und 300 Pixel hohes, schwarzes Bild. Das Schwarz, das wir hier zu sehen bekommen, ist der Alpha-Kanal. Dieser ermöglicht mittels Graustufen Transparenz zu erzeugen. Je dunkler das Grau, umso durchsichtiger. Da wir eine schwarze Fläche sehen ist unser Bild - dem Prinzip nach also gerade "durchsichtig". Die Transparenz funktioniert jedoch nur in Zusammenhang mit einer Farbe, auf die der Alpha-Kanal "projiziert" man sagt "gelegt" wird.

Mit ImageDestroy schließen wir den offenen Bild-Strom ordnungsgemäß, da wir ihn ja ausgeben und nicht mehr brauchen.

Die Bild-Ausgabe Funktionen ermöglichen es übrigens auch noch ein Bild in einer Datei abzuspeichern. Gib dazu einfach einen zweiten Parameter mit dem Pfad an:

<?php
$bild = ImageCreateTrueColor(400,300); //32bit Farben
ImagePNG($bild,'bild.jpg');
ImageDestroy($bild);
?>


Diese PNG Datei wird nun nicht sofort ausgegeben - deshalb brauchen wir den Auszeichner auch nicht mehr - sondern sofort in die Datei "bild.jpg" gespeichert. Du kannst auch einen Pfad wie "C:Eigene DateienEigene Bilderild.jpg" angeben, sofern du in diesem Verzeichnis Schreibrechte hast (was auf Windows grundsätzlich der Fall ist).

Die Funktion "ImageJPEG" hat sogar noch einen dritten Parameter: Qualität. Speicherst du mit ImageJPEG ein Bild als Datei ab, kannst du als dritten Parameter noch eine Zahl von 0 bis 100 angeben. 0 steht für schlechteste Qualität und 100 für die Beste:
<?php
$bild = ImageCreateTrueColor(400,300); //32bit Farben
ImageJPEG($bild,'bild.jpg',85); //Qualität: 85%
ImageDestroy($bild);
?>


Farben
Jede Farbe, die man im Bild verwenden will, muss man vorher mit der Funktion ImageColorAllocate ins Spiel bringen, also innerhalb der Grafik verfügbar machen. Am einfachsten ist es wenn du dir vorstellst, du hast mit dem Bild-Strom eine leere Farbpalette erzeugt. Innerhalb des Bildes kannst du nur jene Farben verwenden, die in der palette drin sind. Festlegen welche Farben in der Palette sind, das tust du mit ImageColorAllocate. Diese erwartet von dir 4 Parameter: Zuerst den Bild-Strom, klar, du musst ihr sagen zu welcher Palette sie die Farbe hinzufügen soll - in unserem Fall: $bild. Die drei anderen Parameter sind der Zahlenwert der drei Farben Rot, Grün und Blau. Du kannst die INtensität von 0 bis 255 angeben. 0 bedeutet besonders intensiv, 255 besonders schwach. Sind die Werte gleich, bewegst du dich in Graustufen. Beispiele:

<?php
header('Content-type: Image/PNG');

$bild = ImageCreate(400, 300);

$weiss = ImageColorAllocate($bild, 255, 255, 255);
$schwarz = ImageColorAllocate($bild, 0, 0, 0);
$rot = ImageColorAllocate($bild, 255, 0, 0);
$gruen = ImageColorAllocate($bild, 0, 255, 0);
$blau = ImageColorAllocate($bild, 0, 0, 255);
$gelb = ImageColorAllocate($bild, 255, 255, 0);
$orange = ImageColorAllocate($bild, 255, 128, 0);

ImagePNG($bild);
ImageDestroy($bild);
?>


Der Umgang mit den Farben ist nun, je nachdem ob man den Bild-Strom mit ImageCreate oder ImageCreateTrueColor erstellt hat ein bisschen unterschiedlich. So wird mit ImageCreate, die erste definierteFarbe automatisch als Hintergrundfarbe verwendet, im obrigen Beispiel also weiß. Würde man die Zeile von $rot zuerst schreiben, wäre das ganze Bild rot.

Ein Strom mit ImageCreateTrueColor macht es einem da nicht so einfach. Für ihn ist das Bild solange leer, solange man keine Objekte reintut. Das Konzept der Hintergrundfarbe kennt er also nicht. Um daher eine Hintergrundfarbe in einen TrueColor-Strom zu kriegen, müsste man ein Rechteck zeichnen, und dieses mit der gewünschten Farbe füllen. Die Objekte die unter PHP/GD verfügbar sind, werden in einem eigenen Tutorium behandelt, das noch folgt.

Transparenz
Wie bereits erwähnt bringt ein Strom von ImageCreateTrueColor einen 8bit Alpha-Kanal mit. Dieser ermöglicht es uns nun Transparente Farben in die Palette zu stellen. Dafür gibt es die Funktion "ImageColorAllocateAlpha". Diese hat nun im Gegensatz zu ImageColorAllocate 5, also einen Parameter mehr. Der fünfte ist nun für die Transparenz zuständig, die einen Wert von 0 bis 127 haben kann, wobei 127 für völlig durchsichtig steht und 0 für gar nciht durchsichtig. Will ich also einen sanften Blauton haben der zu 25% transparent ist, nehm ich als fünften Parameter "32".
<?php
header('Content-type: Image/PNG');
$bild = ImageCreateTrueColor(400, 300);
$blau_halbtransparent = ImageColorAllocateAlpha($bild, 65, 95, 150, 32);
ImagePNG($bild);
ImageDestroy($bild);
?>


Das Skript zeigt dir aber nun nur einen schwarzen kasten, denn wie gesagt, stell ImageCreateTrueColor nur Objekte in Farbe da, der "leere Raum" is immer schwarz. Um die Transparenz einmal zu demonstrieren, hab ich deshalb eine Grafik mit drei Quadraten die alle den selben, 25% transparenten Blauton haben und übereinanderliegen, sodass man sieht, dass es sich tatsächlich um eine "echte" Transparenz handelt:


Nachwort
Wenn du den PHP-Grafik-Strom direkt ausgibst, und mit dem Auszeichner klarstellst, dass es sich um eine Grafik handelt, sollte dir auch klar sein, dass du mitten in einem "normalen" Skript, wo du zum Beispiel eine Datenbank-Abfrage, oder irgendeine andere Prozedur, die zum Schluss Text ausgibt, hast, keine Grafik mit PHP ausgeben kannst. Denn durch den Auszeichner änderst du den Text den PHP ausgibt zur Grafik. Du kannst also mittendrin nicht einfach eine Grafik erstellen anfangen und sie ausgeben, den eine Datei kann nur entweder Text oder Grafik sein. Willst du mitten in deinem Skript eine dynamische Grafik erzeugen, musst du diese in eine eigene Datei auslagern und dann mit HTML, über <img> einbinden:
<html>
<head>
<title>Bild</title>
</head>
<body>
<img src="bild.php" width="400" height="300">
</body>
</html>

Kommentare

Warden
Warden am Mittwoch, 2. November 2005 um 02:05

Danke für das Tutorial. Des hat mir sehr geholfen! Weiter so!

Gruß

Kevin

Markus René Einicher
Markus René Einicher am Freitag, 9. Dezember 2005 um 21:54

Das hört man gern :)