PHP-Bildverarbeitung


Erstellt: 2008-07-21Letzte Änderung: 2016-01-30 [vor 8 Jahren, 2 Monaten, 29 Tagen]

PHP-Bildverarbeitung Ein Tutorial über automatische Bildverarbeitung mit PHP für Webdesigner, um sich viel Arbeit beim Aufarbeiten bzw. Erstellen von Bildern für die eigene Website zu ersparen.

Info 2016-01-30: Hinweise zum Update auf PHP5 in den Besuchereinsendungen!

Einleitung

Info Dies ist eine Überarbeitete Version des alten Tutorials bis Dezember 2009.

Dieses Tutorial baut auf ein Grundgerüst auf, welches im folgenden Abschnitt erarbeitet wird. Danach folgen fünf verschiedene Module, welche je nach Bedarf und unabhängig voneinander in dieses Grundgerüst eingefügt werden können, um das Script um eine oder mehrere der folgenden Funktionen zu erweitern:

Module

Verwendung

Am Ende jedes Abschnittes gibt es den dort vorgestellten Code als PHP-Script zum Download. Die einzelnen Module bestehen wiederum aus zwei Teilen; der Konfiguration und der Prozedur. Die Konfiguration wird an den Anfang des Grundgerüstes kopiert, die Prozedur an die im Grundgerüst markierte Stelle.

Jeglicher Code steht zur Benutzung auf der eigenen Website zur freien Verfügung. :-)

Nach oben

Grundgerüst

Beschreibung

Das Grundgerüst ist ein Script, welches als Parameter den Pfad einer Bilddatei erhält und diese dann im Browser anzeigen soll. Zusätzlich prüft es vorher auf Vorhandensein der Datei und lädt bei Nichtvorhandensein ein Fehlersymbol.

Es bleibt im weiteren Verlauf dieses Tutorials unverändert, es werden lediglich neue Codeabschnitte in das Grundgerüst eingefügt.

Der HTML-Code zum Aufruf dieses Scriptes - nennen wir es einmal image.php - soll dann zunächst wie folgt aussehen:

<img src="image.php?bild=zeilentrafos_gone_wild.jpg" alt="">

Code

Am Anfang des Grundgerüstes steht die Konfiguration. Sie besteht aus einem Satz Konstanten und Variablen, mit denen das Script konfiguriert werden kann. Das sind im Grundgerüst ersteinmal nur der Pfad zum Fehlersymbol und die JPEG-Qualitätseinstellung (dazu kommen wir später).

Den Pfad müsst ihr natürlich auf euer eigenes Fehlersymbol setzen. Meins sieht wie folgt aus und steht euch zur freien Verfügung - unter der Bedingung, dass ihr es NICHT hotlinkt: Fehlersymbol

$image_error = "images/index/notification_error.png";
$image_jpeg_quality = 100;

Der Pfad der anzuzeigenden Bilddatei wird dem Script per GET in der Variable bild übergeben und in $image_filename gespeichert. Wird kein Parameter angegeben, wird das Script mit einer Fehlermeldung abgebrochen.

if (isset($_GET['bild'])) $image_filename = $_GET['bild']; else die("Kein Parameter angegeben.");

Ist der dem Script so übergebene Dateiname nicht vorhanden, soll das Fehlersymbol ausgegeben werden. Wenn sogar das Fehlersymbol fehlt, bricht das Script auch hier mit einer Fehlermeldung ab. Zuerst der Code, dann die Erklärung.

if (!file_exists($image_filename))
{
	if (!file_exists($image_error)) die("Bilddatei und Fehlersymbol nicht vorhanden.");
 
	$image = imagecreatefrompng($image_error);
 
	header("Content-type: image/png");
	imagepng($image);
	imagedestroy($image);
	exit();
}

Bis zur 4. Zeile des obigen Codeschnipsels sollte eigentlich klar sein, was geschieht. Danach aber, ab Zeile 6, befindet sich nun endlich Code zur Ausgabe eines Bildes (in diesem Fall des Fehlersymbols), den wir uns genauer ansehen möchten.

Die Funktion imagecreatefrompng() erhält als ersten und einzigen Parameter den Pfadnamen zu einer PNG-Datei, welche von ihr in den Speicher geladen wird. Der Rückgabewert dieser Funktion ist ein sogenanntes Handle, welches auf unser Bild im Speicher verweist und wir hier in $image speichern.

Analog dazu lässt sich mit der Funktion imagecreatefromjpeg() eine JPEG-Datei laden.

So weit, so gut. Wie bekommen wir das Bild nun vom Speicher unseres Servers in den Browser des Besuchers? header("Content-type: image/png"); sendet dazu ersteinmal einen sogenannten HTTP-Header, der den Browser darauf hinweist, dass nun ein PNG-Bild folgt. Das ist wichtig, ansonsten würde der Browser versuchen, die Bilddatei als Text darzustellen, was natürlich schiefgeht.

Soll dem Browser mitgeteilt werden, dass ein JPEG-Bild folgt, muss in obiger Codezeile natürlich png durch jpeg ersetzt werden.

Nun ist der Browser vorbereitet und wir können ihm das Bild schicken. Das geschieht über die Funktion imagepng(), welche als ersten und einzigen Parameter das Handle unseres Bildes ($image) erhält. PHP schaut nun in den vom Handle adressierten Speicherbereich und haut die Bytes an den Browser heraus.

Wieder analog dazu lässt sich mit der Funktion imagejpeg() eine JPEG-Datei ausgeben. Der erste Parameter ist hier wieder der Pfadname der JPEG-Datei. Über den zweiten zweiten Parameter kann bei Bedarf ein weiterer Dateiname angegeben werden. Das Bild wird dann in einer Datei entsprechenden Namens gespeichert und nicht an den Browser ausgegeben. Das benötigen wir hier aber ersteinmal nicht. Der dritte Parameter bestimmt (in Prozent) die Qualität des auszugebenden JPEG-Bildes (die ja bereits am Anfang des Scriptes als Konstante definiert wurde).

Nun erscheint dem Besucher bereits das Bild im Browser. Jetzt müssen wir abschließend lediglich den vom geladenen Bild reservierten Speicher wieder freigeben; dies geschieht mit der Funktion imagedestroy().

Na also, nun können wir bereits ein Bild, nämlich das Fehlersymbol, ausgeben lassen. Nun folgt der Code, der das gewünschte Bild, wenn es dann doch vorhanden ist, an den Browser ausgibt.

Dabei soll es automatisch zwischen der Ausgabe von PNG- und JPEG-Bilden umschalten können, da es, wie wir weiter oben erfahren mussten, für beide Bildtypen ja unterschiedliche Funktionen gibt.

Die Erkennung des Dateityps erfolgt ganz einfach über die Dateiendung. Der Dateiname wird an den in ihm enthaltenen Punkten (.) in einzelne Array-Elemente aufgespalten. Das letzte Element dieses Arrays enthält dann die Dateierweiterung.

$temp = explode(".", $image_filename);
$image_ext = $temp[count($temp) - 1];

Ein einfacher Switch-Block entscheidet dann, welcher Funktionstyp verwendet werden soll.

switch ($image_ext)
{
	case "jpg": $image_mime = "jpeg"; $image = imagecreatefromjpeg($image_filename); break;
	case "png": $image_mime = "png"; $image = imagecreatefrompng($image_filename); break;
}


Info An dieser Stelle im Script - also nach obigem Codeschnipsel - wird sich später alles weitere Abspielen. Die Codemodule der folgenden Abschnitte dieses Tutorials werden hier hin kopiert und können hier mit der geladenen Bilddatei machen, was sie wollen.


In einer Extravariable $image_mime wurde oben im Switch-Block auch der MIME-Typ (Beschreibt den Dateityp) des Bildes gespeichert. Dieser wird dann in den zu sendenden HTTP-Header eingefügt.

header("Content-type: image/".$image_mime);

Anhand dieses MIME-Typs wird dann auch entschieden, mit welcher Funktion das Bild ausgegeben werden soll.

switch ($image_mime)
{
	case "jpeg": imagejpeg($image, "", $image_jpeg_quality); break;
	case "png": imagepng($image); break;
}

Abschließend muss wieder nur noch der Speicher freigegeben werden und wir sind fertig.

imagedestroy($image);
exit();


Info Zum Schluss kommt noch eine Kleinigkeit hinzu, das folgende Modul E-Mail-Adresse betreffend. Da in diesem Modul kein bereits vorhandenes Bild ausgegeben, sondern ein neues erstellt wird, müssen die obigen Prozeduren und alle eventuell folgenden Modulprozeduren übergangen werden, wenn das Modul E-Mail-Adresse beim Scriptaufruf ausgewählt wird. Alle anderen Prozeduren sind daher in einen einfachen If-Block eingefasst:

if (!isset($_GET['mail']))
{
	...
}


Glückwunsch! Das Grundgerüst ist fertig und du kannst bereits über PHP ein Bild ausgeben lassen. ;-)

Wie gehts nun weiter? In den folgenden Teilen dieses Tutorials werden Module vorgestellt, mit denen sich dieses Grundgerüst erweitern und an die eigenen Bedürfnisse anpassen lässt.

Download

Das auskommentierte, vollständige Grundgerüst gibt es hier zum Download.

Download: phpbildverarbeitung_grundgeruest.php.zip [1.05 kiB]
[2017 Downloads]

Nach oben

Modul: E-Mail-Adresse

Beschreibung

Wer heutzutage seine eigene E-Mail-Adresse im Internet als Klartext veröffentlicht, hat schon verloren und muss sich nicht wundern, regelmäßig von garstigen Spambots über die neusten Viagra-Angebote und die "heißesten" Partnerbörsen informiert zu werden.

Ein wirksamer Schutz gegen die Erfassung der eigenen E-Mail-Adresse durch Spambots kann z.B. die Darstellung der E-Mail-Adresse durch ein Bild anstatt durch Klartext sein.

Für die eigene Website mag man dies noch einfach in Microsoft Paint erledigen können; betreibt man allerdings sein eigenes Gästebuch, in dem auch E-Mail-Adressen veröffentlicht werden, so wird es schon ein wenig schwieriger.

Folgendes Modul hat daher die Aufgabe, E-Mail-Adressen, welche verschlüsselt an das Image-Script übergeben werden, zu entschlüsseln und als Bild auszugeben. Verschlüsselt deshalb, da das Übergeben der E-Mail-Adresse ja als Klartext im <img src="...">-Tag erfolgt und der ganze Aufwand ansonsten vergebens wäre.

Code

Eine tatsächliche Ver-/Entschlüsselung im eigentlichen Sinne findet hier allerdings nicht wirklich statt. Die E-Mail-Adresse wird einfach nur durch die Funktion strrev() geschickt, welche einen String umdreht (aus "hallo" wird "ollah" und umgekehrt). Für unsere Zwecke reicht das ersteinmal.

Die Übergabe der E-Mail-Adresse "spam@lol.com" an das Modul erfolgt per GET über die Variable mail und würde in HTML also wie folgt aussehen:

<img src="image.php?mail=moc.lol@maps" alt="">

Hier zuerst die Konfiguration:

$image_font_size_mail = 2;
$image_font_underline_mail = TRUE;

Erstere Variable legt die Schriftgröße fest, in der die E-Mail-Adresse gezeichnet wird. Zweitere Variable legt fest, ob die Schrift mit einer einfachen Linie unterstrichen werden soll; TRUE = Ja, FALSE = Nein.

Auf gehts! Eine einfache Abfrage ermittelt zuerst, ob eine verschlüsselte E-Mail-Adresse übergeben wurde.

if (isset($_GET['mail']))
{
	...
}

Wenn ja, müssen wir noch prüfen, ob der übergebene String nicht leer ist; ansonsten würde es im Folgenden Fehlermeldungen hageln.

if ($_GET['mail'] === "") die("Keine E-Mail-Adresse angegeben.");

Ist alles in Orndnung, entschlüsseln wir den String ersteinmal, indem wir ihn erneut durch die o. G. Funktion schicken.

$mail_address = strrev($_GET['mail']);

Aus der Länge der E-Mail-Adresse und der Schriftgröße konnen wir nun einfach die Größe des zur Darstellung nötigen Bildes berechnen. Dabei helfen uns die PHP-Funktionen ImageFontWidth() und ImageFontHeight().

$image_width = strlen($mail_address) * imagefontwidth($image_font_size_mail);
$image_height = imagefontheight($image_font_size_mail) + $image_font_underline_mail;

Wie man sieht, addieren wir zur Variable $image_height einfach die Variable $image_font_underline_mail, um die Bildhöhe bei vorhandener Linie um genau einen Pixel zu erhöhen. Das geht, denn TRUE ist in PHP als Eins definiert.

Nun können wir bereits das leere Bild in den berechneten Maßen erstellen.

$image = imagecreate($image_width, $image_height);

Nun müssen noch die Vorder- und Hintergrundfarbe definiert werden, mit denen die Schrift gezeichnet bzw. der Bildhintergrund ausgefüllt wird. In diesem Fall Schwarz auf Weiß (Angabe als getrennte RGB-Werte in der Funktion imagecolorallocate()).

$color_foreground =	imagecolorallocate ($image, 0x00, 0x00, 0x00);
$color_background =	imagecolorallocate ($image, 0xff, 0xff, 0xff);

Nur noch das Bild mit der Hintergrundfarbe füllen...

imagefill($image, 0, 0, $color_background);

...und schon kann die Schrift mit der Funktion imagestring() in der angegebenen Vordergrundfarbe an die Position (0|0) im Bild gezeichnet werden.

imagestring($image, $image_font_size_mail, 0, 0, $mail_address, $color_foreground);

Das Bild nun noch bei Bedarf mit einer Linie (Funktion imageline()) unterstreichen.

if ($image_font_underline_mail)
imageline($image, 0, $image_height - 1, $image_width - 1, $image_height - 1, $color_foreground);

Fertig! Nun muss dem Grundgerüst nur noch mitgeteilt werden, dass ein PNG auszugeben ist und wir haben es geschafft.

$image_mime = "png";

Download

Das auskommentierte, vollständige Modul E-Mail-Adresse gibt es hier zum Download.

Download: phpbildverarbeitung_modul_e_mail_adresse.php.zip [966.00 Bytes]
[3067 Downloads]

Nach oben

Modul: Labeling

Beschreibung

Vielleicht hat der eine oder andere schon bemerkt, dass alle Bilder auf dieser Website in der unteren rechten Ecke den Schriftzug - engl. label - "mosfetkiller.de" tragen. Labeling

Dieser Schriftzug wurde von mir nicht per Hand in jedes Bild eingefügt; dies übernimmt folgendes Modul für mich. ;-)

Im Folgenden soll der Schriftzug "Hallo Welt!" in die Ecke unten rechts des dem Script übergebenen Bildes gezeichnet werden, wobei Schriftgröße, Vorder- und Hintergrundfarbe in der Konfiguration vordefiniert sind.

Code

Das Modul kann über den Parameter $image_labeling_enabled ein- und ausgeschaltet werden; denn vielleicht möchte man ja nicht jedes Bild, sondern z.B. nur JPEGs beschriften. Solch eine Funktion lässt sich im Nachhinein natürlich sehr leicht implementieren.

$image_labeling_enabled = TRUE;
$image_text_label = "Hallo Welt!";
$image_font_size_label = 2;
$image_font_color_foreground_label = "e50000";
$image_font_color_background_label = "ffffff";

Hier wird keine Fehlermeldung erzeugt, wenn $image_text_label nicht gesetzt ist. Wird kein Text angegeben, so wird die Prozedur einfach nicht ausgeführt.

Moment mal, wozu brauchen wir eigentlich eine Hintergrundfarbe? Ganz einfach: Der bloße Schriftzug wird von einer Silhouette, also einer Umrandung in Hintergrundfarbe umgeben, damit er nicht so dünn aussieht.

Bevor es ans Zeichnen des Schriftzuges geht, müssen ersteinmal Vorder- und Hintergrundfarbe gesetzt werden. Die passiert mit der Funktion imagecolorallocate(), welche neben dem Handle des Bildes die drei Farbwerte Rot, Grün und Blau entgegennimmt. Diese sind in der Konfiguration festgehalten - jedoch nicht als einzelne Werte, sondern als RGB-Farbwert in Hex-Schreibweise, so wie man ihn z.B. aus HTML und CSS kennt. Eine einfache Stringfunktion extrahiert die einzelnen Farbkomponenten daraus wieder. Dies geschieht zwei Mal, für die Vorder- und die Hintergrundfarbe.

$_image_font_color_foreground_label = imagecolorallocate($image,
	hexdec(substr($image_font_color_foreground_label, 0, 2)),
	hexdec(substr($image_font_color_foreground_label, 2, 2)),
	hexdec(substr($image_font_color_foreground_label, 4, 2)));

Aus der in der Konfiguration angegebenen Schriftgröße und mithilfe der Funktionen imagefontwidth() und imagefontheight() können wir die Größe des zu zeichnenden Schriftzuges errechnen.

$image_text_label_width = strlen($image_text_label) * imagefontwidth($image_font_size);
$image_text_label_height = imagefontheight($image_font_size);

Und aus der Größe können wir dann die Position berechnen, an die der Schriftzug gezeichnet werden soll. In diesem Fall in die rechte untere Ecke des Bildes, um drei Pixel nach links und zwei Pixel nach unten versetzt.

$image_text_label_x = imagesx($image) - $image_text_label_width - 3;
$image_text_label_y = imagesy($image) - $image_text_label_height - 2;

Nun hindert uns nichts mehr daran, endlich den Schriftzug zu zeichnen.

Allerdings nicht gleich der Schriftzug in Vordergrundfarbe, sondern zuerst die Silhouette in Hintergrundfarbe. Diese wird erzeugt, indem die Schrift gleich mehrmals, jedes Mal um einen Pixel nach oben, unten, links, und rechts verschoben, gezeichnet wird. So sieht das ganze einfach "smoother" aus. 8-)

Den Code dafür spare ich mir an dieser Stelle allerdings, denn er besteht einfach nur aus mehreren Zeilen der folgenden Anweisung, nur eben um einen Pixel in X- bzw. Y-Richtung verschoben. Der tatsächliche Schriftzug in Vordergrundfarbe wird also wie folgt gezeichnet:

imagestring(
	$image,
	$image_font_size,
	$image_text_label_x,
	$image_text_label_y,
	$image_text_label,
	$image_font_color_foreground_label
	);

Fertig! Auf einfache Weise kann nun ein netter Schriftzug jedes eurer Bilder zieren.

Download

Download: phpbildverarbeitung_modul_labeling.php.zip [1,014.00 Bytes]
[2008 Downloads]

Nach oben

Modul: Runde Ecken

Beschreibung

Das folgende Modul rundet die Ecken eines Bildes ab. Dies geschieht, indem einfach an jeder Bildecke Viertelkreise mit wachsendem Radius gezeichnet werden. Diese Kreise haben eine bestimmte Farbe, welche, wenn diese der Farbe des Website-Hintergrundes entspricht, die Ecken des Bildes rundknabbern.

Code

Besagte Farbe der Kreise ist in der Konfiguration definiert. Das Modul kann über den Parameter $image_rounded_edges ein- und ausgeschaltet werden.

$image_rounded_edges = TRUE;
$image_rounded_edges_color = "ffffff";

Die Farbe, in der die Kreise gezeichnet werden sollen, muss vorerst mit der Funktion imagecolorallocate() erstellt werden. Diese nimmt neben dem Handle des Bildes die drei Farbwerte Rot, Grün und Blau entgegen. Diese sind aus Gründen der Kompaktheit in der Konfiguration in einem String als RGB-Farbwert in Hex-Schreibweise - so wie man es aus HTML und CSS kennt - definiert. Eine einfache Stringfunktion extrahiert die einzelnen Farbkomponenten daraus wieder, damit imagecolorallocate() sie verwenden kann.

$color_background = imagecolorallocate($image,
	hexdec(substr($website_color_background, 0, 2)),
	hexdec(substr($website_color_background, 2, 2)),
	hexdec(substr($website_color_background, 4, 2)));

Folgende Schleife zeichnet letztendlich mithilfe der Funktion imagearc() die Viertelkreise mit abnehmenden Radien an die Ecken oben links, oben rechts, unten links und unten rechts. Der erste Parameter ist das Handle des Bildes, die beiden folgenden Parameter sind die Koordinaten des Kreismittelpunktes, die beiden darauf folgenden Parameter sind die Radien des Kreises in X- und Y-Richtung, die Parameter 6 und 7 sind Gradangaben und bestimmen, welcher Kreisausschnitt gezeichnet wird (wie gesagt, es werden nur Viertelkreise gezeichnet). Der letzte Parameter ist die Farbe des zu zeichnenden Viertelkreises.

for ($radius = 26; $radius > 22; $radius--)
{
	imagearc($image, 9, 9, $radius, $radius, 180, 270, $_image_rounded_edges_color);
	imagearc($image, imagesx($image) - 10, 9, $radius, $radius, 270, 0, $_image_rounded_edges_color);
	imagearc($image, 9, imagesy($image) - 10, $radius, $radius, 90, 180, $_image_rounded_edges_color);
	imagearc($image, imagesx($image) - 10, imagesy($image) - 10, $radius, $radius, 0, 90, $_image_rounded_edges_color);
}

Die Koordinaten der Kreismittelpunkte und die Minimal- und Maximalradien der Viertelkreise habe ich experimentell ermittelt. Die Radien lassen sich in obigem Code nicht beliebig steigern, da dann zwischen zwei Kreisen benachbarter Radien bestimmte Pixel frei bleiben und die Ecke so unsauber wird. (Wer nicht weiß, was gemeint ist, darf es gerne selbst ausprobieren ;-)).

Ob man die Ecken seiner Bilder abrunden möchte oder auch nicht, bleibt jedem selbst überlassen und hängt sicherlich auch vom Design der Website ab. Dieses Modul erledigt jedenfalls einen guten Job, wenn man sich dafür entschieden hat. :-)

Download

Download: phpbildverarbeitung_modul_runde_ecken.php.zip [840.00 Bytes]
[2975 Downloads]

Nach oben

Modul: Thumbnail

Beschreibung

Große Bilder in einen dichten Textfluss einzubringen ist meist nicht so schön. Besser ist es, statt der großen Bilder einfach kleine Vorschaubilder anzeigen zu lassen. Klickt der Benutzer darauf, wird das große Bild geöffnet - z.B. in einem neuen Fenster. Ein Beispiel sieht man rechts neben diesem Text.

Um ein Thumbnail eines größeren Bildes anzuzeigen, könnte man entweder einmalig eine verkleinerte Version des großen Bildes erzeugen, in einem gesonderten Ordner abspeichern und anzeigen lassen oder aber mithilfe der width=".." und height=".." Parameter des <img src="..">-Tags das große Bild verkleinert darstellen lassen.

Das Problem bei letzterer Variante ist allerdings, dass der Browser trotzdem vorher das gesamte, große Originalbild herunterladen muss, auch wenn er nur eine stark verkleinerte Version davon anzeigen soll.

Dies treibt serverseitig den Traffic in die Höhe und verlangsamt clientseitig den Seitenaufbau stark. Daher werden wir uns in diesem Fall für die erste Variante entscheiden.

Wird dem Script der Parameter thumb übergeben - ohne Wert, einfach nur dieser Parameter in der URL - so wird zuerst geprüft, ob im Thumbnailordner bereits ein Thumbnail des übergebenen Bildes existiert. Existiert es, so wird es angezeigt; existiert es nicht, so wird es erzeugt und im Thumbnailordner gespeichert. Der Dateiname des Thumbnail entspricht dem des Originalbildes. So weiß das Script, welches Thumbnail zum angegebenen Bild gehört.

Das Thumbnail soll übrigens nicht nur einfach eine verkleinerte Version des Originalbildes sein, sondern soll auch noch von einem Rahmen umgeben und mit einem Lupensymbol ("Klick mich!") verziert werden.

Der HTML-Code zum Anzeigen eines Thumbnails soll dann wie folgt aussehen:

<img src="image.php?bild=zeilentrafos_gone_wild.jpg&thumb" alt="">

Code

Warnung Die Prozedur dieses Moduls muss vor allen anderen Modulprozeduren stehen, da sie diese beeinflusst (runde Ecken und die Bildbeschriftung werden über die entsprechenden Enable-Parameter deaktiviert).

Die Konfiguration dieses Moduls hält zuersteinmal die beiden Pfade zu Thumbnailorder und Lupensymbol. Beide Pfade müsst ihr selbstverständlich noch an eure eigene Website anpassen.

Das auf dieser Website zu findende Lupensymbol gibt es hier zum Download und steht euch zur freien Verfügung - unter der Bedingung, dass ihr es NICHT hotlinkt: Lupensymbol

$image_thumb_path = "images/content/thumbs/";
$image_thumb_symbol_magnify_path = "images/index/symbol_magnify.png";

Desweiteren sind in der Konfiguration die Höhe des zu erzeugenden Thumbnails, die beiden Farben des Thumbnail-Rahmens und des Thumbnail-Hintergrunds und die JPEG-Qualität des zu speichernden Thumbnails festgehalten.

Eine Angabe der Hintergrundfarbe ist erforderlich, da das Lupensymbol um einige Pixel nach rechts versetzt ins Bild gezeichnet wird und somit übersteht. Die rechts freie Fläche wird dann in der angegebenen Hintergrundfarbe gefüllt, welche der Hintergrundfarbe der Website entsprechen sollte.

$image_thumb_height = 100;
$image_thumb_color_border = "cccccc";
$image_thumb_color_background = "ffffff";
$image_thumb_jpeg_quality = 80;

Ein einfacher If-Block prüft zunächst, ob der URL-Parameter thumb gesetzt ist (und nicht gerade eine E-Mail-Adresse ausgegeben werden soll). Wenn ja, kann es losgehen.

if (!isset($_GET['mail']) && isset($_GET['thumb']))
{
	...
}

Damit das Script überprüfen kann, ob das gewünschte Thumbnail bereits existiert oder erst noch erstellt werden muss, muss zuerst eine einheitliche Struktur zur Dateibenennung festgelegt werden. Dabei wird aus dem in bild übergebenen Dateinamen ein Pfad zur gewünschten Thumbnaildatei im Thumbnailordner generiert. Dies kann auf zweierlei Wegen erfolgen, wovon im Code der Modulprozedur jeweils eine ausgewählt und die andere auskommentiert werden muss. Standardmäßig ist Methode 1 gewählt.

Methode 1 schneidet vom in bild übergebenen Dateinamen den Pfad ab und ersetzt diesen durch den Pfad zum Thumbnailordner. Beispiel: Aus images/content/testbild.jpg wird testbild.jpg, woraus dann, kombiniert mit dem Thumbnailordnerpfad, images/thumbs/testbild.jpg wird. Diese Methode eignet sich nur, wenn alle dem Script übergebenen Bilder aus dem gleichen Verzeichnis stammen. Übergibt man dem Script z.B. nacheinander zwei Bilder ordner1/test.jpg und ordner2/test.jpg, so hätten beide das gleiche Thumbnail, was natürlich schiefgeht. Jedoch hat diese Methode den Vorteil, dass die Dateinamen der Thumbnails kürzer und daher besser lesbar sind.

Die Funktion explode() trennt den Dateinamen an den Slashes bzw. Backslashes in ein Array auf. Das jeweils letzte Element des Arrays enthält dann den Dateinamen ohne Pfad.

$image_filename_without_path = explode("/", $image_filename);	//	Linux
$image_filename_without_path = $image_filename_without_path[count($image_filename_without_path) - 1];
$image_filename_without_path = explode("\"", $image_filename_without_path);	//	Windoze
$image_filename_without_path = $image_filename_without_path[count($image_filename_without_path) - 1];

Methode 2 schafft Abhilfe, indem vom in bild übergebenen Dateinamen der Pfad nich abgeschnitten, sondern nur so modifiziert wird, dass er mit in den Dateinamen passt; konkret werden Slashes (Linux) und Backslashes (Windows) durch Unterstriche ersetzt. Beispiel: Aus images/content/testbild.jpg wird images_content_testbild.jpg, woraus dann, kombiniert mit dem Thumbnailordnerpfad, images/thumbs/images_content_testbild.jpg wird. Diese Methode eignet sich für ein universelles Thumbnailverzeichnis.

Die Funktion str_replace() ersetzt alle Slashes bzw. Backslashes im Dateinamen durch Unterstriche.

$image_filename_without_path = str_replace("/", "_", $image_filename);	//	Linux
$image_filename_without_path = str_replace("\"", "_", $image_filename_without_path);	//	Windoze

Natürlich kann man auch vollständig auf einen in der Konfiguration definierten Thumbnailpfad verzichten und diesen Dynamisch aus dem in bild übergebenen Dateinamen extrahieren. Diese Methode ist hier nicht beschrieben, kann jedoch ohne größeren Aufwand implementiert werden.

Der vollständige Pfad zum Thumbnail kann nun zusammengebaut werden:

$image_thumb_filename = $image_thumb_path.$image_filename_without_path;

Der Moment der Wahrheit; nun wird geprüft, ob das Thumbnail bereits existiert oder erst noch generiert werden muss.

if (!file_exists($image_thumb_filename))
{
	...
}

Ist die Datei nicht vorhanden, beginnt man mit dem Erzeugen des Thumbnails. Zuerst wird die Breite des Thumbnails berechnet; die Höhe ist ja bereits in der Konfiguration vorgegeben.

$image_thumb_width = imagesx($image) * ($image_thumb_height / imagesy($image));

Nun wird das Lupensymbol geladen. Achtung: Wenn man ein JPEG als Lupensymbol verwendet, muss in folgender Zeile die Funktion imagecreatefromjpeg verwendet werden. Anschließend wird die Größe des Lupensymbols ermittelt.

$image_thumb_symbol_magnify = imagecreatefrompng($image_thumb_symbol_magnify_path);

$image_thumb_symbol_magnify_width = imagesx($image_thumb_symbol_magnify);
$image_thumb_symbol_magnify_height = imagesy($image_thumb_symbol_magnify);

Das noch leere Thumbnail kann nun erzeugt werden. Dabei wird es um die halbe Breite des Lupensymbols verbreitert. Wie gesagt, das Lupensymbol wird nach rechts versetzt und liegt daher nur halb auf dem Vorschaubild.

$image_thumb = imagecreatetruecolor(
	$image_thumb_width + $image_thumb_symbol_magnify_width / 2,
	$image_thumb_height
	);

Zur Erzeugung der Hintergrundfarbe (und ebenso der Rahmenfarbe) wird die in der Konfiguration in einem String als RGB-Hexwert gespeicherte Hintergrundfarbe mithilfe der Stringfunktion substr() wieder in ihre Komponenten zerlegt und an die Funktion imagecolorallocate() übergeben. Das eben frisch erstelle Thumbnail wird dann mit dieser Farbe ausgefüllt.

$_image_thumb_color_background = imagecolorallocate($image,
	hexdec(substr($image_thumb_color_background, 0, 2)),
	hexdec(substr($image_thumb_color_background, 2, 2)),
	hexdec(substr($image_thumb_color_background, 4, 2)));

imagefill($image_thumb, 0, 0, $_image_thumb_color_background);

Die Funktion imagecopyresampled kopiert nun eine herunterskalierte Version des Originalbildes in das Thumbnail.

imagecopyresampled(
	$image_thumb, $image,
	0, 0, 0, 0,
	$image_thumb_width, $image_thumb_height, imagesx($image), imagesy($image)
	);

Den Rahmen des Thumbnails zeichnet die Funktion imagerectangle().

imagerectangle($image_thumb, 0, 0, $image_thumb_width - 1, $image_thumb_height - 1, $_image_thumb_color_border);

Nun muss nur noch das Lupensymbol ins Thumbnail kopiert werden...

imagecopy($image_thumb, $image_thumb_symbol_magnify,
	imagesx($image_thumb) - $image_thumb_symbol_magnify_width,
	imagesy($image_thumb) - $image_thumb_symbol_magnify_height,
	0, 0, $image_thumb_symbol_magnify_width, $image_thumb_symbol_magnify_height);

...und dann kann das Thumbnail endlich gespeichert werden und der Speicher freigegeben werden.

imagejpeg($image_thumb, $image_thumb_filename, $image_thumb_jpeg_quality);
imagedestroy($image_thumb);

Im Part hinter dem If-Block existiert das Thumbnail nun auf jeden Fall. Das vom Grundgerüst geladene Bild wird nun einfach durch das Thumbnail ersetzt und wir sind fast fertig.

$image_filename = $image_thumb_filename;
 
imagedestroy($image);
$image = imagecreatefromjpeg($image_filename);

Letztendlich müssen nur noch das Labeling und die runden Ecken ausgeschaltet werden, falls diese aktiviert waren. Aus diesem Grund muss die Thumbnail-Modulprozedur auch vor allen anderen stehen, damit das Abschalten oben genannter Module auch funktioniert.

$image_labeling_enabled = FALSE;
$image_rounded_edges_enabled = FALSE;

Fertig! Mithilfe dieses Moduls ist es ab jetzt ein Leichtes, dynamische Thumbnails zu erzeugen. Im HTML-Code kann man das Thumbnail dann einfach mit dem Originalbild verlinken. Oder aber man bedient sich eines Minimums an JavaScript und lässt sich das Originalbild in einem PopUp-Fenster anzeigen. Der Code dafür kann z.B. wie folgt aussehen:

<a href="image.php?bild=zeilentrafos_gone_wild.jpg" onclick="OpenWindow(this.href, 656, 496); return false">
	<img src="image.php?bild=zeilentrafos_gone_wild.jpg&thumb" alt="Thumbnail">
</a>

Ein Problem ist allerdings, dass man hier die Maße des zu öffnenden Fensters angeben muss. Bei unterschiedlich großen Bildern muss man also jedes mal erst die Größe des Bildes ermitteln und in den Link eintragen. Außerdem sollte man zu jeder Koordinate noch 16 Pixel addieren, da - zumindest Firefox, in anderen Browsern habe ich das nicht getestet - immer einen weißen Rahmen um das Bild freilässt und das Bild so nicht in voller Größe angezeigt werden würde.

Auf dieser Website erledigt ein selbstgeschriebenes Template-System die dynamische Erzeugung des oben genannten Thumbnail-Codes, sodass ich die Größe der Fenster nie manuell angeben muss. Dies ist nur zu empfehlen.

Download

Download: phpbildverarbeitung_modul_thumbnail.php.zip [1,6 KiB]
[2142 Downloads]

Nach oben

Modul: Highlight

Beschreibung

Wer auf dieser Website den Cursor einmal ganz oben rechts über den Button "Suchen" schweifen lässt, wird feststellen, dass dieser etwas heller wird. Dieser Effekt wird erreicht, indem per CSS bei einem hover-Ereignis das Hintergrundbild des Buttons gegen eine leicht hellere Version davon ausgetauscht wird. Diese hellere Version des Bildes kann man entweder mit einer Bildbearbeitungssoftware erstellen, oder aber dynamisch erzeugen lassen. Letztere Methode soll im Folgenden hier beschrieben werden.

Zum Erstellen eines gehighlighteten (was für ein Wort :-P) Bildes wird in der URL des Scriptaufrufes einfach der Parameter highlight (ohne nähere Definition, einfach nur der Parameter) angehängt.

<img src="image.php?bild=zeilentrafos_gone_wild.jpg&highlight" alt="">

Code

Im Grunde benötigt man zum Aufhellen des Bildes nur eine einzige Codezeile:

imagefilter($image, IMG_FILTER_BRIGHTNESS, $image_highlight_amount);

Der letzte Parameter der Funktion imagefilter() bestimmt dabei das Maß der Aufhellung und ist in der Konfiguration definiert:

$image_highlight_amount = 20;

Das Problem an der Sache ist jedoch, dass besagte Funktion nur zur Verfügung steht, wenn PHP mit der GD-Library kompiliert wurde. Unter Umständen ist dies bei manchen Webhostern nicht der Fall und die Funktion kann nicht verwendet werden. Daher folgt nun meine selbstgeschriebene Version dieser Funktion, die den gleichen Effekt erzeugt.

In einer Schleife werden einfach die Farbwerte aller Pixel des Bildes ausgelesen (Funktion imagecolorat(), ein festes Offset wird zu jeder deren Farbkomponenten addiert (werden von der Funktion imagecolorsforindex() in einem Array geliefert) und der Pixel wird mit diesen Werten neu gezeichnet (Funktion imagesetpixel(). Dabei darf keine Farbkomponente einen Wert von über 255 annehmen, ansonsten wird der betreffende Pixel u. U. schwarz.

for($x = 0; $x < imagesx($image); $x++)
{
	for($y = 0; $y < imagesy($image); $y++)
	{
		$index = imagecolorat($image, $x, $y);
		$rgb = imagecolorsforindex($image, $index);
 
		$red = $rgb['red'] + $image_highlight_amount; if ($red > 255) $red = 255;
		$green = $rgb['green'] + $image_highlight_amount; if ($green > 255) $green = 255;
		$blue = $rgb['blue'] + $image_highlight_amount; if ($blue > 255) $blue = 255;
 
		$color = imagecolorallocate($image, $red, $green, $blue);
 
		imagesetpixel($image, $x, $y, $color);
	}
}

Ob die Funktion imagefilter() zur Verfügung steht, lässt sich übrigens einfach mithilfe der Funktion function_exists() überprüfen:

if (function_exists("imagefilter"))
{
	//	imagefilter() verwenden
}
else
{
	//	Ersatzroutine verwenden
}

Fertig! War doch ganz leicht. ;-) In CSS wird das ganze wie folgt implementiert:

#Button input.button       { background-image: url(button.png); }
#Button input.button:hover { background-image: url(image.php?bild=button.png&highlight); }

Download

Download: phpbildverarbeitung_modul_highlight.php.zip [844.00 Bytes]
[2058 Downloads]

Nach oben

Besuchereinsendungen

2016-01-30 • Tobias Mädel:

Wollte dir nur kurz mitteilen, dass dein Wasserzeichen-Script nicht mehr funktioniert, wenn man die aktuelle PHP Version verwendet. Die Funktion imagestring wurde verändert, sodass sie als 6.Argument (Farbe) keinen Hex-String mehr annimmt, sondern nur noch ein zuvor erstelltes Farbhandle von imagecolorallocate.

Hier gibt es nun beispielhaft einen reparierten Code zum Download:

Download: phpbildverarbeitung-fixed-tobias-maedel.zip [1.49 kiB]
[1773 Downloads]


2009-06-25 • Marco Seiller (Thunderbolt):

Habe dein PHP-Bildverarbeitung Tutorial gesehen und ausprobiert. Bin aber Anfangs gescheitert (bei der Flut von Variablen im fertigen Script verliert man schonmal den Überblick...).

Nach einiger Zeit, ca. 2 Wochen, in denen ich mich intensiver mit PHP auseinandergesetzt habe und z.T. selber programmiert habe (https://littleserver.homeftp.org/Graph.php und https://littleserver.homeftp.org/Stats.php sind komplett selbstgemacht, brauchen aber noch das entsperechende Bash-Script)), habe ich beschlossen, nur das nötigste (naja erstmal nur das Text-Einfügen) zu übernehmen. Nach einigen Schwierigkeiten (musste zwei Dateien verwenden (image_send.php und imagetxt.php)) habe ich letzendlich auch Erfolg gehabt.

imagetxt.php ist zum Anzeigen auf einer Website. Parameter für imagetxt.php: Fullscale (Orginalgrösse), Thumb (Thumbnail). Ohne Parameter wird das Bild auf die unter "weder Thumbnail noch Fullscale" angegebene Grösse gebracht.

Download: graphstats_marcoseiller-1.0.zip [4.41 kiB]
[1392 Downloads]

Nach oben