Ändern der Größe und Bearbeitung von Bildern in PHP (mit Beispielen)
German (Deutsch) translation by Ines Willenbrock (you can also view the original English article)
In meinem vorherigen Tutorial haben wir die grundlegende Bildbearbeitung mit der PHP GD-Bibliothek besprochen. In diesem Tutorial habe ich eine kurze Einführung in die Bibliothek gegeben und Ihnen gezeigt, wie Sie Bilder aus einer Datei laden oder in PHP von Grund auf neu erstellen. Danach lernten wir, wie man ein Bild mit GD zuschneiden, dreht, skaliert und dreht. Ich habe die imagefilter()-Funktion behandelt, um verschiedene Filter auf Bildressourcen anzuwenden, die im Skript geladen sind. Ich habe auch einige nützliche Funktionen in GD wie imagesx() und imagesy() erwähnt, um die Breite und Höhe des geladenen Bildes zu erhalten.
Am Ende meines letzten GD-Tutorials haben Sie gelernt, wie Sie die Bibliothek verwenden, um grundlegende Aufgaben wie das Ändern der Größe aller Bilder in einem Verzeichnis oder das Anwenden von Filtern wie Graustufen auf sie zu automatisieren, bevor Sie das Endergebnis speichern. Wenn Sie die PHP GD-Bibliothek noch nie zuvor verwendet haben, würde ich vorschlagen, dass Sie diesen GD-Einführungsartikel durchgehen, bevor Sie diesen lesen.
In diesem Tutorial erfahren wir mehr über viele weitere nützliche Funktionen in GD und wie sie verwendet werden können, um mehr unserer Bildbearbeitungsaufgaben zu automatisieren.
Bearbeiten von Bildern mithilfe einer Faltungsmatrix
Mit Ausnahme der Pixel an den Rändern ist jedes Pixel in einem Bild von acht weiteren Pixeln umgeben. Effekte wie Unschärfe oder Kantenerkennung werden für jedes Pixel in Abhängigkeit vom Wert dieses Pixels und den Werten der umgebenden Pixel berechnet. Bei der Kantenerkennung beispielsweise impliziert eine starke Farbänderung, dass wir die Kante eines Objekts im Bild erreicht haben. Zum Beispiel zeigt ein plötzlicher Wechsel von Weiß zu Braun im Bild unten die Grenze der Tasse und des Tisches an.
Eine einfache Möglichkeit, diese Art von Filter zu spezifizieren, ist die sogenannte "Faltungsmatrix". GD liefert die Funktion imageconvolution($image,$matrix,$div,$offset), um eine 3x3-Faltungsmatrix auf eine Bildressource $image anzuwenden.
Der Parameter $matrix ist ein Array aus drei Arrays, von denen jedes drei Gleitkommawerte enthält, d. h. es handelt sich um eine 3x3-Matrix. Das erste Element des ersten Arrays wird mit dem Farbwert des oberen linken Pixels multipliziert. Ebenso wird das zweite Element des ersten Arrays mit dem Farbwert des Pixels direkt über dem zentralen Pixel multipliziert. Die endgültige Farbe des Pixels erhält man, indem man das Ergebnis all dieser Multiplikationen addiert und dann durch $div für die Normalisierung dividiert. Die Normalisierung hält den endgültigen Farbwert im Allgemeinen unter 255.
Wie wir gesehen haben, wird der Parameter $div als Divisor für das Ergebnis der Faltung verwendet, um seinen Wert zu normalisieren. Der Parameter $offset hingegen wird verwendet, um einen Versatzwert für alle Farben anzugeben. Wie sich dies auf das Endergebnis auswirkt, sehen Sie in den folgenden Beispielen.
Beispiele für Faltung
Hier ist eine Liste einiger verschiedener Faltungsmatrizen, die wir auf das Bild einer Tasse auf einem Tisch angewendet haben.
Box-Unschärfe
1 |
$box_blur = array([1, 1, 1], [1, 1, 1], [1, 1, 1]); |
2 |
imageconvolution($im_php, $box_blur, 9, 0); |
Box-Unschärfe funktioniert, indem jedes Pixel mit seinen Nachbarn gemittelt wird. Wir setzen den Wert des Divisors auf 9, da die Summe aller Elemente in den drei Arrays 9 ist.
Schärfen
1 |
$sharpen = array([0, -1, 0], [-1, 5, -1], [0, -1, 0]); |
2 |
imageconvolution($im_php, $sharpen, 1, 0); |
Schärfen funktioniert, indem die Unterschiede zwischen jedem Pixel und seinen Nachbarn übertrieben werden. Dadurch werden die Kanten etwas klarer. Im Falle von Schärfen ist der Divisor immer noch 1, da die Summe aller Elemente in den drei Arrays 1 ist.
Prägen
1 |
$emboss = array([-2, -1, 0], [-1, 1, 1], [0, 1, 2]); |
2 |
imageconvolution($im_php, $emboss, 1, 0); |
Die Prägematrix ähnelt der Schärfmatrix, nur dass die Werte oben links negativ und unten rechts positiv sind – das erzeugt den Prägeeffekt. Die Summe aller Elemente im Falle der Prägefaltungsmatrix ist 1, so dass wir uns keine Sorgen um Normalisierung oder Farbversatz machen müssen.
Kantenerkennung
1 |
$edge_detect = array([-1, -1, -1], [-1, 8, -1], [-1, -1, -1]); |
2 |
imageconvolution($im_php, $edge_detect, 1, 0); |
3 |
imageconvolution($im_php, $edge_detect, 1, 255); |
Die Kantenerkennung ähnelt dem Schärfen, aber der Effekt ist noch stärker. Außerdem wird dem ursprünglichen Wert des Bildes nicht mehr Gewicht beigemessen als den Nachbarn - das bedeutet, dass wir uns nur um die Kanten kümmern, nicht um die ursprünglichen einfarbigen Bereiche.
Bei der Kantenerkennung ist die Summe aller Arrayelemente 0. Dies bedeutet, dass das Bild, das wir erhalten, meistens schwarz ist, es sei denn, es gibt eine scharfe Farbänderung, die im Allgemeinen an den Rändern von Objekten auftritt. Das meist schwarze Bild kann durch Setzen des Offset-Parameters auf 255 in Weiß umgewandelt werden.
Das folgende Bild zeigt das Ergebnis all dieser Faltungsmatrizen.



Funktionen zum Kopieren von Bildern
PHP GD hat viele Funktionen, um einen Teil eines Bildes zu kopieren und dann die Größe zu ändern oder zusammenzuführen. Bei der Verwendung dieser Funktionen ist es wichtig, sich daran zu erinnern, dass PHP die obere linke Ecke einer Bildressource als Ursprung betrachtet. Ein positiver x-Wert führt Sie rechts vom Bild und ein positiver y-Wert führt Sie weiter nach unten.
Die einfachste dieser Funktionen ist imagecopy( $dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h). Das Quellbild wird auf ein Zielbild kopiert. Die Parameter $dst_x und $dst_y bestimmen die obere linke Ecke, in die das kopierte Bild eingefügt wird. Die Parameter $src_x, $src_y, $src_w und $src_h bestimmen den rechteckigen Teil des Quellbilds, der an das Ziel kopiert wird.
Sie können diese Funktion verwenden, um Bilder zuzuschneiden, indem Sie ein Bild von Grund auf mit imagecreatetruecolor() erstellen und das Zuschneiderechteck des Quellbildes hineinkopieren. Sie können es auch verwenden, um Wasserzeichen auf Bildern hinzuzufügen, aber Sie müssen bedenken, dass bei dieser Methode die Größe des Wasserzeichens nicht entsprechend der Größe unserer Bilder geändert werden kann.
Eine Lösung für dieses Problem ist die Verwendung der Funktion imagecopyresized( $dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h). Es akzeptiert alle Parameter von imagecopy() und zwei zusätzliche Parameter, um die Größe des Zielbereichs zu bestimmen, in den das Quellbild kopiert wird.
Die imagecopyresized()-Funktion ist nicht perfekt, da sie das Bild nicht sehr gut nach oben und unten skaliert. Sie können jedoch eine bessere Größenänderung erhalten, indem Sie die imagecopyresampled()-Funktion verwenden, die alle die gleichen Parameter akzeptiert.
Kopieren mit Transparenz
Es gibt zwei weitere Funktionen im Zusammenhang mit dem Kopieren von Bildern, die Sie sehr nützlich finden werden: imagecopymerge() und imagecopymergegray().
Die Funktion imagecopymerge( $dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct) ähnelt imagecopy(), wobei der zusätzliche parameter $pct die Transparenz des kopierten Bildes bestimmt. Ein Wert von 0 bedeutet keine Transparenz, und ein Wert von 100 bedeutet vollständige Transparenz. Dies wird eine große Hilfe sein, wenn Sie den Inhalt des Hauptbildes nicht vollständig hinter Ihrem Wasserzeichen verstecken möchten.
Die Funktion imagecopymergegray() hingegen verwendet den letzten Parameter, um das Quellbild in Graustufen zu konvertieren. Wenn es auf 0 gesetzt ist, verliert das Quellbild seine gesamte Farbe. Wenn es auf 100 festgelegt ist, bleibt das Quellbild nicht betroffen.
Beispiel für Bildkopie
Im folgenden Beispiel wird die Funktion imagecopy() verwendet, um die rechte Hälfte eines Bildes in sein Negativ zu verwandeln. Andere Funktionen wie imagefilter() und imagescale(), die in diesem Codeausschnitt verwendet wurden, haben wir bereits im vorherigen Tutorial besprochen.
1 |
$im_php = imagecreatefromjpeg('fish-mosaic.jpg'); |
2 |
$im_php = imagescale($im_php, 800); |
3 |
$im_php_inv = imagescale($im_php, 800); |
4 |
|
5 |
$im_width = imagesx($im_php); |
6 |
$im_height = imagesy($im_php); |
7 |
|
8 |
imagefilter($im_php_inv, IMG_FILTER_NEGATE); |
9 |
imagecopy($im_php, $im_php_inv, $im_width/2, 0, $im_width/2, 0, $im_width/2, $im_height); |
10 |
|
11 |
$new_name = 'fish-mosaic-half-negate.jpg'; |
12 |
imagejpeg($im_php, $new_name); |
Hier erstellen wir zwei Kopien des Originalbildes, die jeweils auf 800 Pixel Breite verkleinert wurden. Danach verwenden wir die Funktion imagefilter(), um ein Negativ der Bildressource $img_php_inv zu erstellen. Die rechte Hälfte dieses Negativbildes wird dann mit der Funktion imagecopy() auf das Originalbild kopiert.
Dies war eine sehr grundlegende Verwendung der imagecopy()-Funktion. Sie können die Ergebnisse unten sehen. Sie können das Bild auch in kleinere Abschnitte oder Streifen unterteilen, um interessantere Bildeffekte zu erstellen. Wir werden die imagecopymergegray()-Funktion im Code-Snippet unten verwenden, um viel mehr Streifen im ursprünglichen Fischbild zu erstellen.
1 |
$im_php = imagecreatefromjpeg('fish-mosaic.jpg'); |
2 |
$im_php = imagescale($im_php, 800); |
3 |
$im_php_bw = imagescale($im_php, 800); |
4 |
|
5 |
$im_width = imagesx($im_php); |
6 |
$im_height = imagesy($im_php); |
7 |
|
8 |
$stripes = 200; |
9 |
for($i = 0; $i < $stripes; $i++) { |
10 |
if($i%2 == 0) { |
11 |
imagecopymergegray($im_php, $im_php_bw, $i*$im_width/$stripes, 0, $i*$im_width/$stripes, 0, $im_width/$stripes, $im_height, 0); |
12 |
} else { |
13 |
imagecopymergegray($im_php, $im_php_bw, $i*$im_width/$stripes, 0, $i*$im_width/$stripes, 0, $im_width/$stripes, $im_height, 100); |
14 |
}
|
15 |
}
|
16 |
|
17 |
imagefilter($im_php, IMG_FILTER_CONTRAST, -255); |
18 |
imagefilter($im_php, IMG_FILTER_COLORIZE, 250, 0, 0, 100); |
19 |
|
20 |
$new_name = 'fish-mosaic-stripes.jpg'; |
21 |
imagejpeg($im_php, $new_name); |
Das obige Codebeispiel verwendet eine ähnliche Strategie wie im vorherigen Beispiel, aber dieses Mal haben wir das Bild in kleinere Streifen unterteilt, die in Graustufen umgewandelt oder basierend auf dem Wert der Variablen $i unverändert bleiben. Nachdem wir alle Kopierzusammenführungsvorgänge abgeschlossen haben, wenden wir zwei Filter auf das Bild an, um die Streifen hervorzuheben.
Die folgende Abbildung zeigt das Endergebnis dieser beiden Funktionen in Verbindung mit verschiedenen Bildfiltern.



Einbetten von Wasserzeichen oder anderen Informationen in Bilder
Einige Organisationen fügen ihren Bildern Wasserzeichen hinzu, um deutlich zu machen, dass sie das Bild besitzen. Es hilft auch bei der Markenerkennung und hält andere Menschen davon ab, die Bilder unverhohlen zu kopieren. Dank PHP GD ist das Einbinden Wasserzeichen in Bildern eine einfache Aufgabe.
1 |
$im_php = imagecreatefromjpeg('waterfall.jpg'); |
2 |
$watermark = imagecreatefrompng('watermark.png'); |
3 |
$im_width = imagesx($im_php); |
4 |
$im_height = imagesy($im_php); |
5 |
|
6 |
$watermark = imagescale($watermark, $im_width/5); |
7 |
$wt_width = imagesx($watermark); |
8 |
$wt_height = imagesy($watermark); |
9 |
|
10 |
imagecopy($im_php, $watermark, 0.95*$im_width - $wt_width, 0.95*$im_height - $wt_height, 0, 0, $wt_width, $wt_height); |
11 |
|
12 |
$new_name = 'waterfall-watermark.jpg'; |
13 |
imagejpeg($im_php, $new_name); |
Im obigen Codeausschnitt haben wir zwei verschiedene Bildressourcen mit imagecreatefromjpeg() für das Hauptbild bzw. imagecreatefrompng() für das Wasserzeichen erstellt. Die Breite und Höhe des Hauptbildes bestimmen wir mit den Funktionen imagesx() und imagesy().
Nicht alle Bilder, die Sie mit einem Wasserzeichen versehen möchten, haben die gleichen Abmessungen. Wenn Sie die Größe des Wasserzeichens nicht basierend auf den Abmessungen des Hauptbildes ändern, könnte es seltsam aussehen. Beispielsweise könnte ein 200px-Wasserzeichen auf einem 1000px-Bild gut aussehen, aber es wird für ein 600px breites Bild zu groß sein, und es könnte auf einem 2400px breiten Bild zu klein aussehen.
Daher verwenden wir die imagescale()-Funktion, um das Wasserzeichen immer bei einem Fünftel der ursprünglichen Bildbreite zu halten. Wir verwenden dann die Funktion imagecopy(), um das Wasserzeichen an der richtigen Stelle zu platzieren. Hier ist das Endergebnis des obigen Codeausschnitts.



Neben Wasserzeichen können Sie auch andere Informationen hinzufügen, z. B. den Ort, an dem ein Foto aufgenommen wurde, oder den Zeitpunkt, zu dem ein Foto aufgenommen wurde.
Abschließende Gedanken
Nachdem wir in unserem vorherigen Tutorial die Grundlagen der Bildbearbeitung behandelt hatten, lernten wir einige andere nützliche Funktionen in der GD-Bibliothek auf. Im ersten Teil des Tutorials wurde erläutert, wie wir Bilder in PHP mit der Faltungsmatrix manipulieren können. Ich habe auch einige Beispiele für die Faltungsmatrix-Operation gezeigt, um Ihnen zu helfen, zu verstehen, wie PHP zu den Farbwerten verschiedener Pixel kommt.
Im zweiten Teil des Tutorials wurde erklärt, wie sie einen Teil eines Bildes kopieren und / oder in der Größe ändern, um es an anderer Stelle einzufügen. Dies ist praktisch, wenn wir einem Bild etwas wie ein Wasserzeichen oder einen Zeitstempel hinzufügen möchten.
Versuchen Sie, all diese Funktionen zu nutzen, um einige interessante Bildeffekte zu erstellen!



