Advitum.de auf Google+

jQuery: Bilder zuschneiden direkt im Browser

jQuery: Bilder zuschneiden direkt im Browser
VN:F [1.9.22_1171]
Bewertung: 4.4/5 (21 Stimmen abgegeben)
Von am
Kategorien: JavaScript, jQuery, PHP, Programmieren, Tutorials

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.

jQuery: Bilder zuschneiden direkt im Browser, 4.4 out of 5 based on 21 ratings

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.

Die Auswahl-Oberfläche
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&amp;x=' . $x . '&amp;y=' . $y . '&amp;w=' . $w . '&amp;h=' . $h . '&amp;tw=200&amp;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.

Es wird nur der Ausschnitt gezeigt
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!

jQuery: Bilder zuschneiden direkt im Browser, 4.4 out of 5 based on 21 ratings

Jetzt seid ihr dran!

Teilt eure Meinung mit uns in den Kommentaren, gebt eine Bewertung für diesen Artikel ab und teilt ihn in Social Networks!

Über

Ich bin ein junger Webdesigner und Programmierer aus Lüdenscheid und blogge auf Advitum.de über meine Erfahrungen im Web. Meine Themenschwerpunkte liegen im Bereich der Web-Programmierung mit PHP, JavaScript, Html und anderen Script- Programmier- und Markup-Sprachen, der Nutzung von CMS wie Typo3, Wordpress etc. und der Effekt-Hascherei mit Photoshop. Seit 2008 blogge ich auf Advitum.de—mal mehr, mal weniger regelmäßig—über alles, was mich so interessiert. Wenn dir mein Blog gefällt, freue ich mich immer sehr über Feedback in Form von Kommentaren und E-Mails.

Kommentare zu diese Artikel

Schreibe jetzt einen Kommentar!

Jake schrieb am Antworten

Hi,

echt super einfach… ich habe damit einen icongenerator programmiert, welcher bilder im png und im ico format zurückgibt.

Grüße

Jake

    Jake schrieb am Antworten

    und danke noch für dein super erklärtes howto

    Lars Ebert schrieb am Antworten

    Hi Jake, vielen Dank. Kann man dein Script irgendwo in Aktion erleben?

Florian schrieb am Antworten

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!

    Lars Ebert schrieb am Antworten

    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.

    $(document).ready(function()
    {
    	$('#cropimage').Jcrop(
    	{
    		width: 200,
    		height: 300,
    		onSelect: function(coords)
    		{
    			$('#cropimagefield').val(coords.x + ':' + coords.y + ':' + coords.w + ':' + coords.h);
    		}
    	});
    });

    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

schubagga schrieb am Antworten

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?

Chris schrieb am Antworten

Ich bekomme immer angezeigt, dass die Grafik fehler enthält und deswegen nicht angezeigt werden kann. Woran mag das liegen? Ich habe irgendwo gelesen, dass man eine php-Bibliothek einbinden muss?

Mim schrieb am Antworten

Klingt alles sehr schön verständlich, durch das schrittweise Vorgehen auch schön motiviert.

Allerdings wird mir nicht ganz klar, ob hier eine beschnittene Datei erzeugt wird, oder ob nur die Anzeige beschnitten ist.

Ich will diverse Ausschnitte ein und desselben Bildes anzeigen und auch verschieben können, mein JavaScript (das dies kann) läuft aber unter WIN8 nicht mehr und ich suche nach einer Möglichkeit, die Anweisung “” zum laufen zu bringen.

leider habe ich noch nie mit PHP was gemacht, kann also diese Teile Deines Tutorials nicht nachvollziehen.

    Lars Ebert schrieb am Antworten

    Hallo Mim,

    das Originalbild wird nicht angefasst, aber mit PHP werden aus diesem Bild quasi Teile kopiert und dann zum Nutzer geschickt. Der Nutzer kann diesen Ausschnitt aber nicht in Echtzeit verschieben, da dann jedes mal mit PHP ein neues Bild erzeugt werden müsste.

    Wenn ich deine Anforderung richtig verstanden habe, würde ich das Bild als Hintergrundbild eines Divs verwenden, dann kannst du die Größe und Hintergrundposition mit jQuery.css dynamisch verändern.

Tristan S. schrieb am Antworten

Hei, tolles tutorial! Alles gut erklärt etc.
Aber… vor Schritt 2 hast du ja 2 Varianten vorgestellt und die erste gewählt. Wenn ich die zweite richtig verstanden habe würde ich die mehr bevorzugen…
Meine Nutzer sollen einen 1:1 Ausschnitt (Wie das geht hast du ja in einem Kommentar erwähnt) auswählen und wenn sie “Weiter” anklicken soll dieser Ausschnitt in einem Speziellem Ordner als neue Datei, also neues Thumbnail gespeichert werden. Wie sieht das Script dazu aus? Würde mich riesig freuen wenn du das mal “Tutorialst” :)
MfG Tristan

    Lars Ebert schrieb am Antworten

    Hallo Tristan, hier müsste nur der PHP-Teil des Tutorials angepasst werden. Ich habe mir das notiert und werde bei Gelegenheit einen Artikel dazu schreiben.

Florian schrieb am Antworten

Vielen Dank für das detaillierte Tutorial! Ich frage mich nur was der Zwischenschritt soll, dass du erst in der Datenbank speicherst und dann erst das Bild erstellst.. Warum ist das flexibler? Warum nicht direkt das Bild erstellen? Sehe da keine Vorteile..

Diese Artikel könnten dir auch gefallen