jQuery: Bilder zuschneiden direkt im Browser

Für die meisten Bildergalerien hat es bisher ausgereicht, wenn ein zufälliger Bildausschnitt als Vorschaubild ausgeschnitten wird. Deshalb war es bisher nicht nötig, dem Nutzer die Möglichkeit zu geben, direkt im Browser einen Bildausschnitt zu wählen. Doch vor kurzem stand ich vor der Aufgabe, für eine junge Fotografin aus Iserlohn eine Bildergalerie zu programmieren. Da die Bilder auf der Internetseite im Vordergrund stehen sollten, mussten sie besser in Szene gesetzt werden.
In diesem Artikel soll es darum gehen, wie man eine Nutzeroberfläche zum Zuschneiden von Bildern realisieren kann. Mit dem JavaScript-Framework jQuery und ein wenig PHP ist dies tatsächlich nicht schwer.
Schritt 1: Die Nutzeroberfläche
An dieser Stelle gehen wir einmal davon aus, dass der Nutzer bereits ein Bild hochgeladen hat. Nun soll ihm eine Oberfläche zum Zuschneiden des Bildes angezeigt werden. Dafür benötigen wir als erstes das jQuery-Plugin jCrop. Dieses Plugin bietet viele Methoden, um eine solche Oberfläche zu erstellen.
Nachdem das Plugin eingebunden wurde, zeigen wir nun das Bild an, dass der Nutzer gerade hochgeladen hat. Da wir nicht wissen, wie groß das Bild ist, skalieren wir das Bild automatisch mit PHP.
<img alt="Bild" src="/slir/w500/bild1.jpg" id="cropimage" />
Noch einmal zur Erläuterung: Hier wird also das Bild »bild1.jpg« angezeigt, allerdings mit einer maximalen Breite von 500 Pixeln. Wichtig ist, dass wir hier dem Bild eine eindeutige ID geben, in diesem Fall »cropimage«.
Damit der Nutzer das zugeschnittene Bild auch speichern kann, fügen wir jetzt noch ein Formular hinzu.
<form action="index.php" method="post"> <img alt="Bild" src="/slir/w500/bild1.jpg" id="cropimage" /> <input type="hidden" id="cropimagefield" name="cropimage" /> <input type="submit" value="Speichern" /> </form>
Das versteckte Feld benutzen wir gleich, um die Koordinaten des Bildausschnittes zu übermitteln. Aber bis jetzt haben wir nichts weiter als ein Bild und einen Submit-Button. Was noch fehlt, ist die Funktionalität, den Bildausschnitt zu wählen. Deshalb fügen wir jetzt ein bisschen JavaScript hinzu.
$(document).ready(function()
{
$('#cropimage').Jcrop(
{
onSelect: function(coords)
{
$('#cropimagefield').val(coords.x + ':' + coords.y + ':' + coords.w + ':' + coords.h);
}
});
});
Das ist der gesamte JavaScript-Code, den wir brauchen. Die erste Zeile sorgt dafür, dass die Zuschneide-Funktionen erst aktiviert werden, wenn das Bild geladen ist. Mit Jcrop() machen wir das Bild zu einer Auswahl-Oberfläche. Und mit dem onSelect-Event speichern wir beim Ändern der Auswahl die Koordinaten in das versteckte Formularfeld.

Dank JavaScript kann jetzt direkt aus dem Bild ein Ausschnitt gewählt werden.
Nach dem Absenden können die Koordinaten wahlweise gespeichert werden oder an ein Script übergeben werden, welches direkt eine Bilddatei erzeugt. Ich habe mich, um flexibel zu bleiben, für die erste Variante entschieden und speichere die Koordinaten einfach in einer Datenbank.
Schritt 2: Verarbeiten der Auswahl
Was wir jetzt haben sind nichts weiter als eine Hand voll Zahlen. Der nächste Schritt muss sein, aus diesen Koordinaten ein Bild zu erstellen.
Dazu legen wir ein neues Script an, welches wir später einfach im scr-Attribut eines image-Tags verwenden können. Dort können wir per Parameter die Koordinaten der Auswahl übergeben und es wird das zugeschnittene Bild zurückgegeben.
Zur Verdeutlichung hier einmal, wie der Code aussehen könnte, der die Bilddatei ausgibt:
$coords = '74:46:350:233';
list($x, $y, $w, $h) = explode(':', $coords);
echo '<img src="crop.php?image=flower.jpg&x=' . $x . '&y=' . $y . '&w=' . $w . '&h=' . $h . '&tw=200&th=300" alt="Blume" />';
Diesen Aufruf an die Datei crop.php müssen wir jetzt natürlich verarbeiten. Dort wird nun endlich das Bild zugeschnitten und zurückgegeben.
//Gewünschte Größe des Resultats
$targ_w = $_GET['tw'];
$targ_h = $_GET['th'];
//Bildqualität
$jpeg_quality = 90;
//Wo liegt das Bild?
$src = 'pfad/zum/bild/' . $_GET['image'];
//Der Bildausschnitt
$x = $_GET['x'];
$y = $_GET['y'];
$w = $_GET['w'];
$h = $_GET['h'];
//Das Ausgangs- und das Zielbild werden erzeugt
$ausgangsbild = imagecreatefromjpeg($src);
$zielbild = ImageCreateTrueColor($targ_w, $targ_h);
//Nun wird der gewünschte Bildausschnitt aus dem Ausgangsbild ins Zielbild kopiert und dabei auf die richtige Größe skaliert
imagecopyresampled($zielbild, $ausgangsbild, 0, 0, $x, $y, $targ_w, $targ_h, $w, $h);
//Schließlich wird noch das fertige Bild ausgegeben
header('Content-type: image/jpeg');
imagejpeg($dst_r,null,$jpeg_quality);
exit;
Dieses Script ist im Grunde jetzt schon fertig, allerdings hat es noch einen Schönheitsfehler, der alles durcheinander bringt. Wir blicken noch einmal zurück zur Oberfläche für den Nutzer:
<img alt="Bild" src="/slir/w500/bild1.jpg" id="cropimage" />
Hier wird das Bild, falls es breiter als 500 Pixel ist, auf eine Breite von 500 Pixeln verkleinert. Dadurch beziehen sich in diesem Fall aber auch die Auswahl-Koordinaten auf die verkleinerte Version des Bildes. Also müssen wir diesen Sonderfall noch betrachten, da sonst der Bildausschnitt falsch gewählt wird. Glücklicherweise müssen wir nicht viel an unserem Script ändern:
//Gewünschte Größe des Resultats
$targ_w = $_GET['tw'];
$targ_h = $_GET['th'];
//Bildqualität
$jpeg_quality = 90;
//Wo liegt das Bild?
$src = 'pfad/zum/bild/' . $_GET['image'];
//Wenn das Bild breiter als 500 Pixel ist, müssen wir die Koordinaten korrigieren
if(imagesx($img_r) > 500)
{
//Um diesen Faktor wurde das Bild skaliert, also müssen die Koordinaten wieder auf die volle Größe zurückgerechnet werden!
$factor = imagesx($img_r) / 500;
$x = $_GET['x'] * $factor;
$y = $_GET['y'] * $factor;
$w = $_GET['w'] * $factor;
$h = $_GET['h'] * $factor;
}
else
{
$x = $_GET['x'];
$y = $_GET['y'];
$w = $_GET['w'];
$h = $_GET['h'];
}
//Das Ausgangs- und das Zielbild werden erzeugt
$ausgangsbild = imagecreatefromjpeg($src);
$zielbild = ImageCreateTrueColor($targ_w, $targ_h);
//Nun wird der gewünschte Bildausschnitt aus dem Ausgangsbild ins Zielbild kopiert und dabei auf die richtige Größe skaliert
imagecopyresampled($zielbild, $ausgangsbild, 0, 0, $x, $y, $targ_w, $targ_h, $w, $h);
//Schließlich wird noch das fertige Bild ausgegeben
header('Content-type: image/jpeg');
imagejpeg($dst_r,null,$jpeg_quality);
exit;
Und in der Tat wird jetzt der richtige Bildausschnitt angezeigt.

Das PHP-Script sorgt dafür, dass aus dem Originalbild der richtige Bildausschnitt gezeigt wird.
Fazit
Wie man sieht, ist es gar nicht so kompliziert, Nutzer beliebige Bildausschnitte aus einem Bild auswählen zu lassen und diese hinterher mit PHP zuzuschneiden. Dank jQuery und seinen unzähligen Plugins ist auch diese Aufgabe zu bewältigen.
Was sagt ihr?
Hättet ihr gedacht, dass es so einfach ist, so eine vermeintlich komplizierte Funktion umzusetzen? Was würdet ihr anders machen? Habt ihr Erfahrung mit dieser oder ähnlichen Techniken? Eure Meinung interessiert mich brennend, also hinterlasst mir doch einen Kommentar!
Links zum Thema
- Jcrop » Examples and Demos
- Fotos in Alben ordnen – Drag & Drop mit jQuery
- 28 Fresh jQuery Tutorials
- jQuery: Bilder zuschneiden – image crop
Über den Autor:
Ich bin ein junger Webentwickler und Programmierer aus Iserlohn. Mit PHP, HTML etc. bin ich praktisch aufgewachsen. Seit 2010 blogge ich auf Advitum.
Facebook, Twitter & Kommentare:








Hinterlasse eine Antwort
Hi,
echt super einfach… ich habe damit einen icongenerator programmiert, welcher bilder im png und im ico format zurückgibt.
Grüße
Jake
und danke noch für dein super erklärtes howto
Hi Jake, vielen Dank. Kann man dein Script irgendwo in Aktion erleben?
Also erstmal vielen Dank für das super Tutorial, ich hab jedoch noch eine Frage. Ich möchte, dass der Rahmen eine fixe Größe hat, sprich vorausgewählt ist, und der User diesen nur mehr verschieben kann um so seine Auswahl zu tätigen. Funktioniert das?
Danke schon mal!
Hallo Florian,
vielen Dank für dein Lob. Leider scheint grade die Internetseite von jCrop nicht zu funktionieren, sonst hätte ich da nachgeschaut. Aber ich meine im Kopf zu haben, dass du einfach mit width und height die festen Maße angeben kannst.
Ich habe das aber jetzt nur geraten und auch nicht getestet. Schau am besten mal, ob es funktioniert und gib hier ein Feedback. Ich werde auch nochmal auf der Seite schauen, wenn sie denn wieder erreichbar ist.
Hier kann man übrigens auch jCrop downloaden, der Server scheint mir öfters unerreichbar zu sein: http://webscripts.softpedia.com/scriptDownload/Jcrop-Download-61597.html
schönes und vor allem mal verständliches (;) tutorial.
Aber semakaya.de scheint an sedo verkauft zu sein, kann man das tool noch woanders sehen?
Wie jCrop im Allgemeinen funktioniert, kann man gut in den Beispielen direkt für jCrop sehen! Der Rest vom Tool sah eigentlich recht unspektakulär aus.