() translation by (you can also view the original English article)
Wollten Sie schon immer eine universelle, benutzerfreundliche Methode zum Ändern der Größe Ihrer Bilder in PHP? Genau dafür sind PHP-Klassen gedacht - wiederverwendbare Funktionen, die wir aufrufen, um die Drecksarbeit hinter den Kulissen zu erledigen. Wir werden lernen, wie wir unsere eigene Klasse erstellen, die sowohl gut aufgebaut als auch erweiterbar ist. Die Größenänderung sollte einfach sein. Wie einfach? Wie wäre es mit drei Schritten!
Einführung
Um Ihnen einen kurzen Einblick zu geben, was wir mit unserer Klasse erreichen wollen, sollte die Klasse sein:
- Einfach zu verwenden
- Formatunabhängig. Öffnen, ändern Sie die Größe und speichern Sie verschiedene Bildformate.
- Intelligente Größe - Keine Bildverzerrung!
Hinweis: Das ist kein Tutorial zum Erstellen von Klassen und Objekten. Diese Fähigkeit würde zwar helfen, ist jedoch nicht erforderlich, um diesem Tutorial zu folgen.
Es gibt viel zu besprechen - Fangen wir an.
Schritt 1 Vorbereitung
Wir fangen einfach an. Erstellen Sie in Ihrem Arbeitsverzeichnis zwei Dateien: eine mit dem Namen index.php und die andere mit der Größe resize-class.php



Schritt 2 Aufrufen des Objekts
Um Ihnen eine Vorstellung davon zu geben, was wir erreichen möchten, codieren wir zunächst die Aufrufe, mit denen wir die Größe der Bilder ändern. Öffnen Sie Ihre index.php-Datei und fügen Sie den folgenden Code hinzu.
Wie Sie sehen können, gibt es eine nette Logik für das, was wir tun. Wir öffnen die Bilddatei, legen die Abmessungen fest, auf die die Größe des Bildes geändert werden soll, und die Art der Größenänderung.
Dann speichern wir das Bild und wählen das gewünschte Bildformat und die Bildqualität. Speichern und schließen Sie Ihre index.php-Datei.
1 |
// *** Include the class
|
2 |
include("resize-class.php"); |
3 |
|
4 |
// *** 1) Initialize / load image
|
5 |
$resizeObj = new resize('sample.jpg'); |
6 |
|
7 |
// *** 2) Resize image (options: exact, portrait, landscape, auto, crop)
|
8 |
$resizeObj -> resizeImage(150, 100, 'crop'); |
9 |
|
10 |
// *** 3) Save image
|
11 |
$resizeObj -> saveImage('sample-resized.gif', 100); |
Sie können sehen, dass wir eine JPG-Datei öffnen, aber ein GIF speichern. Denken Sie daran, es geht um Flexibilität.
Schritt 3 Klassenskelett
Es ist die objektorientierte Programmierung (OOP), die dieses Gefühl der Leichtigkeit ermöglicht. Stellen Sie sich eine Klasse, wie ein Muster, vor. Sie können die Daten kapseln - ein weiterer Jargonbegriff, der wirklich nur das Ausblenden der Daten bedeutet. Wir können diese Klasse dann immer wieder verwenden, ohne den Größenänderungscode neu schreiben zu müssen. Sie müssen nur die entsprechenden Methoden aufrufen, wie wir es in Schritt 2 getan haben. Sobald unser Muster erstellt wurde, erstellen wir Instanzen dieses Musters, die als Objekte bezeichnet werden.
"Die Konstruktfunktion, die als Konstruktor bezeichnet wird, ist eine spezielle Klassenmethode, die von der Klasse aufgerufen wird, wenn Sie ein neues Objekt erstellen."
Beginnen wir mit der Erstellung unserer Größenänderungsklasse. Öffnen Sie Ihre Datei resize-class.php. Im Folgenden finden Sie eine wirklich grundlegende Skelettstruktur, die ich als "resize" bezeichnet habe. Beachten Sie die Kommentarzeile der Klassenvariablen. Hier fangen wir an hinzuzufügen unserer wichtigen Klassenvariablen später.
Die Konstruktfunktion, die als Konstruktor bezeichnet wird, ist eine spezielle Klassenmethode (der Begriff "Methode" entspricht der Funktion, wenn jedoch über Klassen und Objekte gesprochen wird, wird häufig der Begriff Methode verwendet), die von der Klasse beim Erstellen aufgerufen wird ein neues Objekt. Das macht es für uns geeignet, einige Initialisierungen durchzuführen - was wir im nächsten Schritt tun werden.
1 |
Class resize |
2 |
{
|
3 |
// *** Class variables
|
4 |
|
5 |
public function __construct() |
6 |
{
|
7 |
|
8 |
}
|
9 |
}
|
Beachten Sie, dass dies ein doppelter Unterstrich für die Konstruktmethode ist.
Schritt 4 Der Konstruktor
Wir werden die obige Konstruktormethode ändern. Zunächst übergeben wir den Dateinamen (und den Pfad) unseres Bildes, dessen Größe geändert werden soll. Wir werden diese Variable $fileName aufrufen.
Wir müssen die mit PHP übergebene Datei öffnen (genauer gesagt die PHP GD Library), damit PHP das Bild lesen kann. Wir machen das mit der benutzerdefinierten Methode 'openImage'. Ich werde erfahren, wie diese Methode
funktioniert in einem Moment, aber im Moment müssen wir das Ergebnis als Klassenvariable speichern. Eine Klassenvariable ist nur eine Variable - aber sie ist spezifisch für diese Klasse. Erinnern Sie sich an den zuvor erwähnten Kommentar zur Klassenvariablen? Fügen Sie 'image' als private Variable hinzu, indem Sie 'private $image;' eingeben. Wenn Sie die Variable auf "Private" setzen, legen Sie den Bereich dieser Variablen so fest, dass nur die Klasse darauf zugreifen kann. Von nun an können wir unser geöffnetes Image, eine sogenannte Ressource, aufrufen, was wir später tun werden, wenn wir die Größe ändern.
Speichern wir dabei die Höhe und Breite des Bildes. Ich habe das Gefühl, dass diese später nützlich sein werden.
Sie sollten jetzt Folgendes haben.
1 |
Class resize |
2 |
{
|
3 |
// *** Class variables
|
4 |
private $image; |
5 |
private $width; |
6 |
private $height; |
7 |
|
8 |
function __construct($fileName) |
9 |
{
|
10 |
// *** Open up the file
|
11 |
$this->image = $this->openImage($fileName); |
12 |
|
13 |
// *** Get width and height
|
14 |
$this->width = imagesx($this->image); |
15 |
$this->height = imagesy($this->image); |
16 |
}
|
17 |
}
|
Die Methoden imagesx und imagesy sind in Funktionen integriert, die Teil der GD-Bibliothek sind. Sie rufen die Breite und Höhe Ihres Bildes ab.
Schritt 5 Öffnen des Bildes
Im vorherigen Schritt rufen wir die benutzerdefinierte Methode openImage auf. In diesem Schritt erstellen wir diese Methode. Wir möchten, dass das Skript für uns nachdenkt. Je nachdem, welcher Dateityp übergeben wird, sollte das Skript bestimmen, welche GD-Bibliotheksfunktion es zum Öffnen des Bildes aufruft. Dies wird leicht erreicht, indem die Dateierweiterung mit einer switch-Anweisung verglichen wird.
Wir übergeben unsere Datei, deren Größe wir ändern möchten, und geben diese Dateiressource zurück.
1 |
private function openImage($file) |
2 |
{
|
3 |
// *** Get extension
|
4 |
$extension = strtolower(strrchr($file, '.')); |
5 |
|
6 |
switch($extension) |
7 |
{
|
8 |
case '.jpg': |
9 |
case '.jpeg': |
10 |
$img = @imagecreatefromjpeg($file); |
11 |
break; |
12 |
case '.gif': |
13 |
$img = @imagecreatefromgif($file); |
14 |
break; |
15 |
case '.png': |
16 |
$img = @imagecreatefrompng($file); |
17 |
break; |
18 |
default: |
19 |
$img = false; |
20 |
break; |
21 |
}
|
22 |
return $img; |
23 |
}
|
Schritt 6 Ändern der Größe
Hier geschieht die Liebe. Dieser Schritt ist wirklich nur eine Erklärung dafür, was wir tun werden - also keine Hausaufgaben hier. Im nächsten Schritt erstellen wir eine öffentliche Methode, die wir aufrufen, um die Größenänderung durchzuführen. Daher ist es sinnvoll, die Breite und Höhe sowie Informationen darüber, wie die Größe des Bilds geändert werden soll, anzugeben. Lassen Sie uns einen Moment darüber sprechen. Es wird Szenarien geben, in denen Sie die Größe eines Bildes auf eine exakte Größe ändern möchten. Großartig, lassen Sie uns dies einschließen. Es wird aber auch Zeiten geben, in denen Sie die Größe von Hunderten von Bildern ändern müssen und jedes Bild ein anderes Seitenverhältnis hat - denken Sie an Porträtbilder. Die Größenänderung auf eine exakte Größe führt zu starken Verzerrungen. Wenn wir uns unsere Optionen ansehen, um Verzerrungen zu vermeiden, können wir:
- Ändern Sie die Größe des Bildes so nah wie möglich an unsere neuen Bildabmessungen, während Sie das Seitenverhältnis beibehalten.
- Ändern Sie die Größe des Bildes so nah wie möglich an unsere neuen Bildabmessungen und schneiden Sie den Rest zu.
Beide Optionen sind je nach Ihren Anforderungen realisierbar.
Ja. Wir werden versuchen, all das zu bewältigen. Um es noch einmal zusammenzufassen:
- Ändern Sie die Größe nach exakter Breite/Höhe. (genau)
- Größenänderung nach Breite - Die genaue Breite wird eingestellt, die Höhe wird entsprechend dem Seitenverhältnis angepasst. (Landschaft)
- Größenänderung nach Höhe - wie Größenänderung nach Breite, jedoch wird die Höhe festgelegt und die Breite dynamisch angepasst. (Porträt)
- Automatische Ermittlung der Optionen 2 und 3. Wenn Sie einen Ordner mit Fotos unterschiedlicher Größe durchlaufen, lassen Sie das Skript bestimmen, wie damit umgegangen werden soll. (Auto)
- Größe ändern, dann zuschneiden. Das ist mein Favorit. Genaue Größe, keine Verzerrung. (Ernte)
Schritt 7 Ändern der Größe. Machen wir das!
Die Größenänderungsmethode besteht aus zwei Teilen. Die erste besteht darin, die optimale Breite und Höhe für unser neues Bild zu erhalten, indem Sie einige benutzerdefinierte Methoden erstellen - und natürlich unsere Größenänderungsoption wie oben beschrieben übergeben. Die Breite und Höhe werden als Array zurückgegeben und auf ihre jeweiligen Variablen gesetzt. Fühlen Sie sich frei, als Referenz zu übergeben - aber ich bin kein großer Fan davon.
Der zweite Teil führt die eigentliche Größenänderung durch. Um die Größe dieses Tutorials gering zu halten, lasse ich Sie die folgenden GD-Funktionen nachlesen:
Wir speichern auch die Ausgabe der imagecreatetruecolor-Methode (ein neues Echtfarbenbild) als Klassenvariable. Fügen Sie 'private $imageResized;' mit Ihren anderen Klassenvariablen.
Die Größenänderung wird von einem PHP-Modul durchgeführt, das als GD-Bibliothek bekannt ist. Viele der von uns verwendeten Methoden werden von dieser Bibliothek bereitgestellt.
1 |
// *** Add to class variables
|
2 |
private $imageResized; |
1 |
public function resizeImage($newWidth, $newHeight, $option="auto") |
2 |
{
|
3 |
|
4 |
// *** Get optimal width and height - based on $option
|
5 |
$optionArray = $this->getDimensions($newWidth, $newHeight, strtolower($option)); |
6 |
|
7 |
$optimalWidth = $optionArray['optimalWidth']; |
8 |
$optimalHeight = $optionArray['optimalHeight']; |
9 |
|
10 |
// *** Resample - create image canvas of x, y size
|
11 |
$this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight); |
12 |
imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height); |
13 |
|
14 |
// *** if option is 'crop', then crop too
|
15 |
if ($option == 'crop') { |
16 |
$this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight); |
17 |
}
|
18 |
}
|
Schritt 8 Der Entscheidungsbaum
Je mehr Arbeit Sie jetzt erledigen, desto weniger müssen Sie tun, wenn Sie die Größe ändern. Diese Methode wählt die Route aus, mit dem Ziel, die optimale Größe und Höhe der Größe basierend auf Ihrer Größenänderungsoption zu ermitteln. Es wird die entsprechende Methode aufgerufen, die wir im nächsten Schritt erstellen werden.
1 |
private function getDimensions($newWidth, $newHeight, $option) |
2 |
{
|
3 |
|
4 |
switch ($option) |
5 |
{
|
6 |
case 'exact': |
7 |
$optimalWidth = $newWidth; |
8 |
$optimalHeight= $newHeight; |
9 |
break; |
10 |
case 'portrait': |
11 |
$optimalWidth = $this->getSizeByFixedHeight($newHeight); |
12 |
$optimalHeight= $newHeight; |
13 |
break; |
14 |
case 'landscape': |
15 |
$optimalWidth = $newWidth; |
16 |
$optimalHeight= $this->getSizeByFixedWidth($newWidth); |
17 |
break; |
18 |
case 'auto': |
19 |
$optionArray = $this->getSizeByAuto($newWidth, $newHeight); |
20 |
$optimalWidth = $optionArray['optimalWidth']; |
21 |
$optimalHeight = $optionArray['optimalHeight']; |
22 |
break; |
23 |
case 'crop': |
24 |
$optionArray = $this->getOptimalCrop($newWidth, $newHeight); |
25 |
$optimalWidth = $optionArray['optimalWidth']; |
26 |
$optimalHeight = $optionArray['optimalHeight']; |
27 |
break; |
28 |
}
|
29 |
return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight); |
30 |
}
|
Schritt 9 Optimale Abmessungen
Wir haben bereits besprochen, was diese vier Methoden bewirken. Sie sind wirklich nur einfache Mathematik, die unsere beste Anpassung berechnen.
1 |
private function getSizeByFixedHeight($newHeight) |
2 |
{
|
3 |
$ratio = $this->width / $this->height; |
4 |
$newWidth = $newHeight * $ratio; |
5 |
return $newWidth; |
6 |
}
|
7 |
|
8 |
private function getSizeByFixedWidth($newWidth) |
9 |
{
|
10 |
$ratio = $this->height / $this->width; |
11 |
$newHeight = $newWidth * $ratio; |
12 |
return $newHeight; |
13 |
}
|
14 |
|
15 |
private function getSizeByAuto($newWidth, $newHeight) |
16 |
{
|
17 |
if ($this->height < $this->width) |
18 |
// *** Image to be resized is wider (landscape)
|
19 |
{
|
20 |
$optimalWidth = $newWidth; |
21 |
$optimalHeight= $this->getSizeByFixedWidth($newWidth); |
22 |
}
|
23 |
elseif ($this->height > $this->width) |
24 |
// *** Image to be resized is taller (portrait)
|
25 |
{
|
26 |
$optimalWidth = $this->getSizeByFixedHeight($newHeight); |
27 |
$optimalHeight= $newHeight; |
28 |
}
|
29 |
else
|
30 |
// *** Image to be resizerd is a square
|
31 |
{
|
32 |
if ($newHeight < $newWidth) { |
33 |
$optimalWidth = $newWidth; |
34 |
$optimalHeight= $this->getSizeByFixedWidth($newWidth); |
35 |
} else if ($newHeight > $newWidth) { |
36 |
$optimalWidth = $this->getSizeByFixedHeight($newHeight); |
37 |
$optimalHeight= $newHeight; |
38 |
} else { |
39 |
// *** Sqaure being resized to a square
|
40 |
$optimalWidth = $newWidth; |
41 |
$optimalHeight= $newHeight; |
42 |
}
|
43 |
}
|
44 |
|
45 |
return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight); |
46 |
}
|
47 |
|
48 |
private function getOptimalCrop($newWidth, $newHeight) |
49 |
{
|
50 |
|
51 |
$heightRatio = $this->height / $newHeight; |
52 |
$widthRatio = $this->width / $newWidth; |
53 |
|
54 |
if ($heightRatio < $widthRatio) { |
55 |
$optimalRatio = $heightRatio; |
56 |
} else { |
57 |
$optimalRatio = $widthRatio; |
58 |
}
|
59 |
|
60 |
$optimalHeight = $this->height / $optimalRatio; |
61 |
$optimalWidth = $this->width / $optimalRatio; |
62 |
|
63 |
return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight); |
64 |
}
|
Schritt 10 Zuschneiden
Wenn Sie sich für eine Ernte entschieden haben - das heißt, Sie haben die Ernteoption verwendet -, haben Sie noch einen kleinen Schritt. Wir werden das Bild aus dem zuschneiden
Center. Das Zuschneiden ist dem Ändern der Größe sehr ähnlich, es werden jedoch einige weitere Größenparameter übergeben.
1 |
private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight) |
2 |
{
|
3 |
// *** Find center - this will be used for the crop
|
4 |
$cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 ); |
5 |
$cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 ); |
6 |
|
7 |
$crop = $this->imageResized; |
8 |
//imagedestroy($this->imageResized);
|
9 |
|
10 |
// *** Now crop from center to exact requested size
|
11 |
$this->imageResized = imagecreatetruecolor($newWidth , $newHeight); |
12 |
imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight); |
13 |
}
|
Schritt 11 Speichern Sie das Bild
Wir kommen dorthin; fast fertig. Es ist jetzt Zeit, das Bild zu speichern. Wir übergeben den Pfad und die gewünschte Bildqualität reicht von 0 bis 100, wobei 100 die beste ist, und rufen die entsprechende Methode auf. Ein paar Dinge, die Sie zur Bildqualität beachten sollten: JPG verwendet eine Skala von 0 bis 100, wobei 100 die beste ist. GIF-Bilder haben keine Einstellung für die Bildqualität. PNGs tun dies, aber sie verwenden die Skala 0-9, wobei 0 die beste ist. Dies ist nicht gut, da wir nicht erwarten können, dass wir uns jedes Mal daran erinnern, wenn wir ein Bild speichern möchten. Wir machen ein bisschen Magie, um alles zu standardisieren.
1 |
public function saveImage($savePath, $imageQuality="100") |
2 |
{
|
3 |
// *** Get extension
|
4 |
$extension = strrchr($savePath, '.'); |
5 |
$extension = strtolower($extension); |
6 |
|
7 |
switch($extension) |
8 |
{
|
9 |
case '.jpg': |
10 |
case '.jpeg': |
11 |
if (imagetypes() & IMG_JPG) { |
12 |
imagejpeg($this->imageResized, $savePath, $imageQuality); |
13 |
}
|
14 |
break; |
15 |
|
16 |
case '.gif': |
17 |
if (imagetypes() & IMG_GIF) { |
18 |
imagegif($this->imageResized, $savePath); |
19 |
}
|
20 |
break; |
21 |
|
22 |
case '.png': |
23 |
// *** Scale quality from 0-100 to 0-9
|
24 |
$scaleQuality = round(($imageQuality/100) * 9); |
25 |
|
26 |
// *** Invert quality setting as 0 is best, not 9
|
27 |
$invertScaleQuality = 9 - $scaleQuality; |
28 |
|
29 |
if (imagetypes() & IMG_PNG) { |
30 |
imagepng($this->imageResized, $savePath, $invertScaleQuality); |
31 |
}
|
32 |
break; |
33 |
|
34 |
// ... etc
|
35 |
|
36 |
default: |
37 |
// *** No extension - No save.
|
38 |
break; |
39 |
}
|
40 |
|
41 |
imagedestroy($this->imageResized); |
42 |
}
|
Jetzt ist auch ein guter Zeitpunkt, um unsere Bildressource zu zerstören und Speicherplatz freizugeben. Wenn Sie dies in der Produktion verwenden, ist es möglicherweise auch eine gute Idee, das Ergebnis des gespeicherten Bildes zu erfassen und zurückzugeben.
Abschluss
Nun, das ist es, Leute. Vielen Dank, dass Sie diesem Tutorial gefolgt sind. Ich hoffe, Sie finden es nützlich. Ich würde mich über Ihr Feedback über die folgenden Kommentare freuen.