JPEG-Grafik mit GD-Library

Bearbeitung von Bildern im Format JPEG

Die GD-Library bietet die Möglichkeit, bestehende Bilder zu öffnen und zu bearbeiten, und neue Bilder zu speichern. Die Bild-Daten können aus Dateien oder Datenbanken stammen, oder nach einem Algorithmus komplett berechnet werde.
PHP Hypertext Processor PHP PHP Hypertext Processor, PHP-Grafik
JPEG-Datei Lesen und Schreiben einer JPEG-Datei
Informationen Information über eine JPEG-Grafik
Pixel lesen Lesen einzelner Bildpunkte (Pixel)
Pixel schreiben Schreiben einzelner Bildpunkte (Pixel), Rendern von Text, Linien & Figuren
Filter Pixel-Manipulationen der Bildverarbeitung
Kopieren Kopieren und Einsetzen von (Teil)-Bildern
Skalieren Vergrößern und Verkleinern von (Teil)-Bildern (Thumbnails)

Lesen und Schreiben einer JPEG-Datei

Die Bild-Datei wird mit Funktion imagecreatefromjpeg geöffnet. Die Daten werden an eine Variable (hier $img) übergeben, die in allen weiteren Funktionen das Bild repräsentiert.
Das Bild wird mit Funktion imagejpeg gespeichert. Mit chmod werden die Zugriffsrechte auf die Datei freigegeben (Linux).
Die Dateinamen aller erzeugten Bilder dieser Seite werden mit Hilfe der aktuellen Uhrzeit erzeugt. So wird ihr Browser gezwungen, die soeben mit PHP erstellte Grafik zu laden, und nicht eine evtl. gleichnamige aus seinem Cache.
Nicht mehr benötigte Bilder werden vom PHP-Script dieser Seite an deren Anfang gelöscht.
Nach Verwendung sollten die verwendeten Resourcen mit Funktion imagedestroy wieder freigegeben werden.
$src = 'glocke.jpg';
$dst = 'gdl160241.png';
// Bild-Datei lesen
$img = imagecreatefromjpeg($src);
// Bild-Datei als JPEG schreiben
imagejpeg($img,$dst);
chmod ($dst,0777);
/* mit Qualitäts-Faktor $q
imagejpeg($img,$dst,$q);
/* Bild-Datei als PNG schreiben
imagepng($img,$dst_png);
*/
imagedestroy($img);
Original:
<img src="glocke.jpg" />
Dieses Bild ist die Ausgangsbasis für alle Beispiele dieser Seite.
Kopie von PHP erzeugt Mit PHP erzeugte Kopie im JPEG-Format:
<img src="gdl160241.jpg">
Live Zeitbedarf = 2.6 ms
Zur Kontrolle wird die Server-Zeit mit Funktion imagestring im Bild eingetragen.

Bildqualität:

Der Standard JPEG bietet variable Kompression: Bildqualität und Dateigröße können gegenläufig eingestellt werden.
Funktion imagejpeg akzeptiert dazu ein 3.Argument (z.B. $q ) als Zahl im Bereich 0..100:
$q=0 ..... starke Kompression, geringe Qualität
$q=100 ... geringe Kompression, hohe Qualität
Die Kompression ist nicht umkehrbar, d.h. aus einem mit q<100 gespeicherten Bild lässt sich das Original-Bild nicht mehr rekonstruieren.
$q = 3
1002 Byte
$q = 10
1279 Byte
$q = 95
5613 Byte

Datenstrom

Nicht immer muss ein erzeugtes oder verändertes Bild als Datei gespeichert werden. Eine Grafik-Datei ist nur dann sinnvoll, wenn sie mehrmals verwendet wird, oder eine bestimmte "Lebensdauer" haben soll.
Alternativ kann man mit Perl oder PHP die Bild-Daten direkt als → Datenstrom an den Browser senden. Das funktioniert am Server sogar etwas schneller, hinterlässt jedoch keine Datei, die Speicherplatz verbraucht und evtl. kurz darauf wieder gelöscht werden muss.
Details zur Erzeugung eines Datenstroms.

Bild-Informationen

Das Beispiel rechts zeigt, wie die Bild-Dimension ermittelt wird:

Die Funktionen filesize und getimagesize (beide im PHP-Modul standard, d.h. immer verfügbar) werden bevorzugt, da sie bereits vor dem Öffnen der Datei angewendet werden. So kann man Fehler durch unlesbare oder übergroße Bilder verhindern.

Die Funktionen imagesx und imagesy werden auf ein geöffnetes oder erzeugtes Bild angewendet.

Live-Live-PHP-PHP:
Größe = 4849 Byte
Breite = 94 Pixel
Höhe = 100 Pixel
// aus dem Dateipfad
$size = filesize($src);
$is = getimagesize($src);
$xmax = $is[0];
$ymax = $is[1];
// aus dem Bild
$xmax = imagesx($img);
$ymax = imagesy($img);
// Ausgabe
print "Groesse = $size Bytes <br />";
print "Breite = $xmax Pixel <br />";
print "Hoehe = $ymax Pixel <br />";

Meta-Informationen

Weitere Daten bieten die Funktionen der PHP-Module exif und iptc
Diese Module sind bei üblichen Web-Providern nicht geladen, sie kommen nur für die Anwendung am eigenen PC oder Server in Frage.
Beide Module bieten Zugang zu den (vor allem von Digital-Cameras) in jeder Bild-Datei gespeicherten Meta-Daten, z.B. Camera-Modell, Datum, Zeit, Blende, Belichtungszeit, Filter, usw.
Leider liefert fast jeder Camera-Hersteller diese Informationen in einem anderen Format, aber für die eigene Camera ist das weniger wichtig.

Pixel lesen

Mit Funktion imagecolorat kann man die Farbe jedes einzelnen Bildpunktes (Pixel) lesen.
Die x-Koordinate läuft wie üblich von links nach rechts, die y-Koordinate jedoch von oben nach unten !
Die Funktion gibt eine ganze Zahl zurück, welche den RGB-Farbwert codiert enthält:
Farbwert = ((R * 256 + G) * 256) + B
Die 3 Zahlenwerte für R,G,B erhalten sie mit Hilfe von → Bit-Operatoren oder mit Funktion imagecolorsforindex
Rechts einige Live-Beispiele aus dem gezeigten Bild.

Das Beispiel rechts zeigt eine Funktion printcolor zur Ausgabe der Hex-Farbwerte von Bildpunkten, angewendet auf einige zufällig gewählte Punkte des Bildes, darunter die Live-Ergebnisse.
(Farbmuster mit → CSS und → Unicode erzeugt).
function printcolor($img,$x,$y) {
$c = imagecolorat($img,$x,$y);
/* mit Bit-Operatoren
$r = ($c>>16) & 0xFF;
$g = ($c>>8) & 0xFF;
$b = $c& 0xFF;
*/
$rgb = imagecolorsforindex($img,$c);
$hex = sprintf('#%02X%02X%02X',
$rgb['red'],$rgb['green'],$rgb['blue']);
print "($x,$y)$hex, ";
}

// Pixel-Stichproben:
$img = imagecreatefromjpeg($src);
for ($i=0;$i<15;$i++) {
$x=rand(0,($xmax-1));
$y=rand(0,($ymax-1));
printcolor($img,$x,$y);
}
Live-Live-PHP-PHP:   (Zufalls)-Punkt(x,y) # Farbcode
(42,6)#010302, (57,76)#6552AB, (55,49)#9186CA, (35,59)#8C81C6, (23,57)#A59DD9, (58,33)#4B398F, (23,68)#8783BE, (38,76)#9488D4, (76,71)#1A1335, (53,82)#091C08, (48,49)#BDB9D2, (37,53)#907FCF, (48,40)#A092E9, (28,39)#7F74B8, (48,56)#7F70AB, ...

Pixel schreiben

Pixel-Farbe setzen

Mit Funktion imagesetpixel kann man die Farbe jedes einzelnen Bildpunktes (Pixel) schreiben.

Die gewünschte Farbe wird vor Verwendung mit Funktion imagecolorallocate definiert, danach mit imagecolordeallocate wieder gelöscht.

Im Beispiel wird in der rechten oberen Ecke ein Quadrat der Größe 20x20=400 Pixel auf Rot rgb(255,0,0) = #FF0000 gesetzt.
// Bild öffnen
$img = imagecreatefromjpeg($src);
// Farbe definieren
$cw=imagecolorallocate($img,255,0,0);
// 400 Pixel ändern
for($x=($xmax-20);$x<$xmax;$x++) {
for($y=0;$y<20;$y++) {
$x = imagesetpixel($img,$x,$y,$cw);
}
}
imagecolordeallocate($img,$cw);
// Bild speichern
imagejpeg($img,$dst);
Rechts das Ergebnis des Beispiel-Programms: Datei von PHP erzeugt Live Zeitbedarf = 1.5 ms

Text rendern

Text-Zeichen werden in Bildpunkte umgewandelt ('Render'-Vorgang).
Im Beispiel rechts wird die Farbe cs auf Gelb rgb(255,255,0) = #FFFF00 gesetzt.
Mit Funktion imagestring wird der Text gerendert und ins Bild eingesetzt.
Argumente der Funktion imagestring:
Ziel-Bild, Schriftgröße [1..5], Ziel-X, Ziel-Y, String, Farbe
Analog arbeiten die Funktionen imagestringup zur senkrechten Beschriftung und imagechar bzw. imagecharup zur Ausgabe eines einzelnen Zeichens.

$cs=imagecolorallocate($img,255,255,0);
$s = 'Probetext';
imagestring($img,3,33,86,$s,$cs);
imagecolordeallocate($img,$cs);
Mit dieser Methode wurde die Server-Zeit in die ↑ Demo-Bilder eingesetzt.

Linien und Figuren

Das Malen unterschiedlicher geometrischer Elemente erfolgt mit einem bequemen Vorrat an Funktionen. Eine gute Beschreibung liefert SelfPHP.
Tipp: Verwenden sie nur solche GD-Funktionen, die auch bei ihrem Provider verfügbar sind.
Details zur Liste der GD-Funktionen.
Datei von PHP erzeugt Live Zeitbedarf = 1.2 ms
Alle Funktionen für geometrische Formen gibt es in 2 Versionen, mit & ohne Farb-Füllung, z.B. imagerectangle und imagefilledrectangle Für das oben gezeigte Beispiel wurden folgende GD-Funktionen eingesetzt:
imagefilledellipse, imagefilledpolygon

Filter

In jedem gängigen Programm zur Bildverarbeitung gibt es die Möglichkeit, ein ganzes Bild oder Teile davon mit Hilfe von Filtern zu verändern, z.B. Änderung von Helligkeit, Kontrast, oder Farbsättigung, Erzeugung von Schwarzweiß-Bildern aus Farbbildern, Scharf- oder Weichzeichnen von Kontrasten, Drehung von Bildern, Farb-Umkehr usw. Dabei werden typische Algorithmen (Rechen-Vorschriften) der Bildverarbeitung einzeln oder in Kombination verwendet. Auch die GD-Library bietet diese Möglichkeiten.
Ein Filter kann individuell programmiert werden (Beispiel), wesentlich rascher arbeiten jedoch die verfügbaren Standard-Filter der Funktion imagefilter.

Individuell programmierte Filter:

Einfache Algorithmen betreffen einzelne Pixel ohne Berücksichtigung ihrer Nachbarn. Das Beispiel zeigt einen einfachen Filter zur Farb-Umkehr.
Dafür müssen alle Bildpunkte in (mindestens) einer Schleife durchlaufen werden.
Jeder Bildpunkt wird gelesen, verarbeitet und wieder geschrieben.
Das sind in diesem Beispiel 94*100=9400 Bildpunkte. Für ein typisches Bild einer Digital-Camera oder für eine → A4-Scan-Seite sind das 2 bis 4 Millionen Pixel.
Dafür wird erheblich Prozessor-Zeit benötigt, daher werden solche Funktionen auf öffentlichen Webservern besser nicht verwendet.

Programmierung:
Mit 2 verschachtelten Schleifen ($x,$y) wird jeder Bildpunkt einzeln adressiert. Die 'alte' Farbe wird mit imagecolorat gelesen und mit imagecolorsforindex decodiert.
Nun folgt der eigentliche Filter - hier die Farb-Umkehrung.
Zuletzt wird die 'neue' Farbe mit imagesetpixel geschrieben.
$img = imagecreatefromjpeg($src);
// Beispiel Farb-Umkehr
for($x=0;$x<$imgxmax;$x++) {
for($y=0;$y<$imgymax;$y++) {
// Pixel-Farbe lesen
$cr = imagecolorat($img,$x,$y);
$rgb = imagecolorsforindex($img,$cr);
// Farbe umkehren
$r = 255 - $rgb['red'];
$g = 255 - $rgb['green'];
$b = 255 - $rgb['blue'];
$cw=imagecolorallocate($img,$r,$g,$b);
// Pixel-Farbe schreiben
imagesetpixel($img,$x,$y,$cw);
imagecolordeallocate($img,$cw);
}
}
// Bild speichern
imagejpeg($img,$dst);
Für die Server lokaler Netze (LANs) oder für komfortable Arbeits-PC gilt das Gegenteil:
Hier werden solche Funktionen sehr vorteilhaft zur vollautomatischen Bearbeitung von Bildern eingesetzt, vor allem für größere Mengen von Bild-Dateien.
Voraussetzung ist lediglich die (kostenlose !) Einrichtung eines Standard → LAMP oder → WAMP Servers - auf heutigen PC eigentlich schon selbstverständlich.
Datei von PHP erzeugt Live Zeitbedarf = 25.6 ms

Geschätzter Zeitbedarf für ein
2-Megapixel Digitalbild:
ca. 5 Sekunden
Ab PHP Version 5 ist die Funktion imagefilter verfügbar:
Damit sind Filter bequem zu programmieren, die Funktion arbeitet angenehm rasch.

Probieren sie die Filter im eigenen LAN oder am eigenen PC, dort ist diese Funktion ideal im Einsatz.
Es ist zu erwarten, dass in Zukunft weitere Filter verfügbar sind - Die Algorithmen sind von üblichen Grafik-Programmen bekannt.

Tipp:
Nicht immer müssen sie die Bild-Datei ändern, um einen gewünschten Filter-Effekt zu erzielen. Beachten sie die → CSS Filter-Funktionen, welche die Anzeige von Bildern beeinflussen und auf Client-Seite (Browser) arbeiten.
IMG_FILTER_BRIGHTNESSHelligkeit ändern
IMG_FILTER_COLORIZEEine Art 'bunter Grauwert'
IMG_FILTER_CONTRASTKontrast ändern
IMG_FILTER_EDGEDETECTKanten-Filter
IMG_FILTER_EMBOSSPräge-Effekt
IMG_FILTER_GAUSSIAN_BLURWeichzeichner
IMG_FILTER_GRAYSCALEFarben → Grauwerte
IMG_FILTER_MEAN_REMOVALEffekt-Filter
IMG_FILTER_NEGATEFarb-Umkehr
IMG_FILTER_SELECTIVE_BLURWeichzeichner
IMG_FILTER_SMOOTHWeichzeichner

Beispiel:
imagefilter ($img, IMG_FILTER_NEGATE)

(Teil)-Bild kopieren

Zunächst wird ein neues Bild $imgn erzeugt. Dafür wird Funktion imagecreatetruecolor verwendet, denn imagecreate kann nur 256 (Index)-Farben verwalten.
Die Abmessung wird in jeder Richtung 10 Pixel größer als das Original-Bild gewählt.
Mit Funktion imagecolorallocate wird die Farbe  'Dunkelrot' rgb(160,0,0) = #A00000 eingestellt und mit imagefilledrectangle der Hintergrund erzeugt.
Das Original-Bild 'img' wird mit Funktion ImageCopy auf das neue Bild 'imgn' kopiert.
Argumente der Funktion ImageCopy:
Ziel-Bild, Quell-Bild, Ziel-x, Ziel-y, Quell-x, Quell-y, Quell-Breite, Quell-Höhe.
// Neues Bild:
$x=104; $y=110
$imgn = imagecreatetruecolor($x,$y);
$f = imagecolorallocate($imgn,160,0,0);
imagefilledrectangle($imgn,0,0,$x,$y,$f);
[ imagefill(0,0,$f) ]
// Kopieren:
ImageCopy($imgn,$img,5,5,0,0,$xmax,$ymax);
// Bild speichern, Rechte freigeben
imagejpeg($imgn,$dst);
chmod ($dst,0777);
Ergebnis:
Das neu erzeugte Bild mit Farbe 'Dunkelrot', darüber ist das komplette Original-Bild kopiert, jedoch um 5 Pixel versetzt. So bleibt vom 'Dunkelrot'-Bild noch ein 5 Pixel breiter Rand.
Datei von PHP erzeugt Live Zeitbedarf = 1.2 ms

(Teil)-Bild skalieren (vergrößern, verkleinern): Thumbnails

Kopieren und Skalieren:

Funktion ImageCopyResized kopiert und skaliert gleichzeitig.
Der kopierte Teil kann vergrößert oder verkleinert werden. Hier wird ein Teil des Original-Bilds vergrößert auf ein 'Dunkelrot'-Bild kopiert.
Argumente der Funktion ImageCopyresized:
Ziel-Bild, Quell-Bild, Ziel-x, Ziel-y, Quell-x, Quell-y, Ziel-Breite, Ziel-Höhe, Quell-Breite, Quell-Höhe
Datei von PHP erzeugt Live Zeitbedarf = 1.2 ms

Thumbnails:

Die Funktion ImageCopyResized wird zur Herstellung von Thumbnails verwendet: Verkleinerte Kopien von Bildern, die zur Übersicht und Vorab-Ansicht verwendet werden.
Hier wird ein Thumbnail in halber Größe des Originals erzeugt.
Komprimieren: Je kleiner das Thumbnail werden soll, desto mehr kann man es komprimieren (Kapitel ↑ Schreiben) - Dieses Beispiel wurde mit q=10 erzeugt.
Datei von PHP erzeugt Live Zeitbedarf = 0.4 ms
Größe = 855 Byte
Verwenden sie keinesfalls (!) die HTML-Attribute height und width zur → Verkleinerung großer Bilder, z.B. für ein 2000x1000 Pixel Bild:
<img src="x.jpg" height="50" width="100" />
Derartige Fehler findet man seit Verbreitung der digitalen Cameras leider immer häufiger.
Web-BesucherInnen müssen dazu das komplette Original-Bild übertragen (das ist in diesem Beispiel die mehr als 400-fache Datenmenge), danach wird es vom Browser wieder verkleinert.
Dieser Aufwand ist unnötig und für Gäste mit Modem-Anschluß untragbar.

Letzte Änderung dieser Seite: 2011-12-01 09:31:09