Was ist der effizienteste Weg, um die Größe großer Bilder in PHP zu ändern?
Ich verwende derzeit die GD- Funktion imagecopyresampled, um hochauflösende Bilder aufzunehmen und sie sauber auf eine Größe für die Webansicht zu verkleinern (ungefähr 700 Pixel breit und 700 Pixel hoch).
Dies funktioniert hervorragend bei kleinen Fotos (unter 2 MB) und der gesamte Größenänderungsvorgang dauert auf dem Server weniger als eine Sekunde. Die Website wird jedoch möglicherweise Fotografen bedienen, die möglicherweise Bilder mit einer Größe von bis zu 10 MB (oder Bilder mit einer Größe von bis zu 5000 x 4000 Pixel) hochladen.
Wenn Sie diese Art der Größenänderung bei großen Bildern ausführen, wird die Speichernutzung tendenziell um einen sehr großen Rand erhöht (größere Bilder können die Speichernutzung für das Skript auf über 80 MB erhöhen). Gibt es eine Möglichkeit, diesen Größenänderungsvorgang effizienter zu gestalten? Sollte ich eine alternative Bildbibliothek wie ImageMagick verwenden ?
Im Moment sieht der Größenänderungscode ungefähr so aus
function makeThumbnail($sourcefile, $endfile, $thumbwidth, $thumbheight, $quality) {
// Takes the sourcefile (path/to/image.jpg) and makes a thumbnail from it
// and places it at endfile (path/to/thumb.jpg).
// Load image and get image size.
$img = imagecreatefromjpeg($sourcefile);
$width = imagesx( $img );
$height = imagesy( $img );
if ($width > $height) {
$newwidth = $thumbwidth;
$divisor = $width / $thumbwidth;
$newheight = floor( $height / $divisor);
} else {
$newheight = $thumbheight;
$divisor = $height / $thumbheight;
$newwidth = floor( $width / $divisor );
}
// Create a new temporary image.
$tmpimg = imagecreatetruecolor( $newwidth, $newheight );
// Copy and resize old image into new image.
imagecopyresampled( $tmpimg, $img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height );
// Save thumbnail into a file.
imagejpeg( $tmpimg, $endfile, $quality);
// release the memory
imagedestroy($tmpimg);
imagedestroy($img);
Hier ist ein Ausschnitt aus den php.net-Dokumenten, die ich in einem Projekt verwendet habe und die einwandfrei funktionieren:
http://us.php.net/manual/en/function.imagecopyresampled.php#77679
quelle
$quality + 1
mit($quality + 1)
? So wie es ist, ändern Sie nur die Größe mit einem nutzlosen zusätzlichen Pixel. Wo ist die Prüfung auf Kurzschluss, wenn$dst_w * $quality
>$src_w
?imagecopyresized()
auch verwendet. Grundsätzlich wird das Bild zuerst auf eine überschaubare Größe geändert (final dimensions
multipliziert mitquality
) und dann erneut abgetastet, anstatt einfach das Bild in voller Größe neu abzutasten. Es kann in einer geringeren Qualität Endbild führen, aber es nutzt weit weniger Ressourcen für größere Bilder alsimagecopyresampled()
allein als Resampling - Algorithmus nur mit einem Bild die Größe von 3 x die endgültigen Dimensionen standardmäßig zu tun hat, im Vergleich zu dem Bild in voller Größe ( Dies kann weitaus größer sein, insbesondere bei Fotos, deren Größe für Miniaturansichten geändert wird.phpThumb verwendet ImageMagick, wann immer dies aus Gründen der Geschwindigkeit möglich ist (ggf. auf GD zurückgreifen), und scheint ziemlich gut zwischenzuspeichern, um die Belastung des Servers zu verringern. Das Ausprobieren ist ziemlich einfach (um die Größe eines Bildes zu ändern, rufen Sie einfach phpThumb.php mit einer GET-Abfrage auf, die den grafischen Dateinamen und die Ausgabedimensionen enthält), damit Sie versuchen können, festzustellen, ob es Ihren Anforderungen entspricht.
quelle
Verwenden Sie bei größeren Bildern libjpeg, um die Größe beim Laden von Bildern in ImageMagick zu ändern. Dadurch wird die Speichernutzung erheblich reduziert und die Leistung verbessert. Mit GD ist dies nicht möglich.
quelle
Aus Ihrer Frage geht hervor, dass Sie ein bisschen neu bei GD sind. Ich werde einige meiner Erfahrungen teilen. Vielleicht ist dies ein wenig abseits des Themas, aber ich denke, es wird für jemanden hilfreich sein, der neu bei GD ist, wie Sie:
Schritt 1, Datei validieren. Verwenden Sie die folgende Funktion, um zu überprüfen, ob die
$_FILES['image']['tmp_name']
Datei eine gültige Datei ist:Schritt 2, Dateiformat abrufen Versuchen Sie die folgende Funktion mit der Erweiterung finfo, um das Dateiformat der Datei (Inhalt) zu überprüfen. Sie würden sagen, warum verwenden Sie nicht einfach
$_FILES["image"]["type"]
, um das Dateiformat zu überprüfen? Weil es nur Dateierweiterung prüft nicht den Dateiinhalt, wenn jemand eine Datei ursprünglich genannt umbenennen World.png zu world.jpg ,$_FILES["image"]["type"]
kehrt jpeg nicht png, so$_FILES["image"]["type"]
kann falsches Ergebnis zurück.Schritt 3, GD-Ressource abrufen GD-Ressource aus zuvor vorhandenen Inhalten abrufen :
Schritt 4, Bildgröße abrufen Jetzt können Sie die Bildgröße mit dem folgenden einfachen Code abrufen:
Nun wollen wir sehen, welche Variable wir dann vom Originalbild erhalten haben:
Schritt 5, Berechnen von Größenargumenten für Bilder Dieser Schritt bezieht sich auf Ihre Frage. Der Zweck der folgenden Funktion besteht darin, Größenänderungsargumente für die GD-Funktion
imagecopyresampled()
abzurufen. Der Code ist etwas lang, funktioniert aber hervorragend und bietet sogar drei Optionen: Strecken, Verkleinern , und Fülle.strecken : Die Dimension des Ausgabebilds entspricht der neuen Dimension, die Sie festgelegt haben. Das Verhältnis von Höhe zu Breite wird nicht eingehalten.
Verkleinern : Die Bemaßung des Ausgabebilds überschreitet nicht die neue Bemaßung, die Sie angeben, und behält das Verhältnis von Bildhöhe zu -breite bei.
Füllen : Die Dimension des Ausgabebilds entspricht der neuen Dimension, die Sie angeben. Bei Bedarf wird das Bild zugeschnitten und in der Größe geändert , und das Verhältnis von Bildhöhe zu -breite wird beibehalten. Diese Option benötigen Sie in Ihrer Frage.
Schritt 6, Größe ändern Bild Verwenden
$args
,$width
,$height
,$format
und $ Ressource , die wir von oben in die folgende Funktion bekam und die neue Ressource des skalierte Bild erhalten:Schritt 7, Neue Inhalte abrufen . Verwenden Sie die folgende Funktion, um Inhalte aus der neuen GD-Ressource abzurufen:
Schritt 8 Erweiterung abrufen, Verwenden Sie die folgende Funktion, um die Erweiterung des Bildformats abzurufen (Hinweis: Das Bildformat entspricht nicht der Bilderweiterung):
Schritt 9 Bild speichern Wenn wir einen Benutzer namens mike haben, können Sie Folgendes tun: Er wird im selben Ordner wie dieses PHP-Skript gespeichert:
Schritt 10 Ressource zerstören Vergessen Sie nicht, GD-Ressource zu zerstören!
oder Sie können Ihren gesamten Code in eine Klasse schreiben und einfach Folgendes verwenden:
TIPPS
Ich empfehle, das vom Benutzer hochgeladene Dateiformat nicht zu konvertieren, da Sie auf viele Probleme stoßen werden.
quelle
Ich schlage vor, dass Sie etwas in diese Richtung arbeiten:
Um ImageMagick im Hintergrund zu verwenden, verschieben Sie die hochgeladenen Dateien in einen temporären Ordner und planen Sie einen CRON-Job, der alle Dateien in JPEG "konvertiert" und die Größe entsprechend ändert. Siehe Befehlssyntax unter: imagemagick-Befehlszeilenverarbeitung
Sie können den Benutzer auffordern, dass die Datei hochgeladen und für die Verarbeitung geplant ist. Der CRON-Job kann so geplant werden, dass er täglich in einem bestimmten Intervall ausgeführt wird. Das Quellbild kann nach der Verarbeitung gelöscht werden, um sicherzustellen, dass ein Bild nicht zweimal verarbeitet wird.
quelle
Ich habe große Dinge über die Imagick-Bibliothek gehört, leider konnte ich sie nicht auf meinem Arbeitscomputer und auch nicht zu Hause installieren (und vertraue mir, ich habe Stunden und Stunden in allen Arten von Foren verbracht).
Nach den Worten habe ich beschlossen, diese PHP-Klasse auszuprobieren:
http://www.verot.net/php_class_upload.htm
Es ist ziemlich cool und ich kann die Größe aller Arten von Bildern ändern (ich kann sie auch in JPG konvertieren).
quelle
ImageMagick ist Multithread-fähig, scheint also schneller zu sein, verbraucht jedoch viel mehr Ressourcen als GD. Wenn Sie mehrere PHP-Skripte parallel mit GD ausführen würden, würden sie ImageMagick für einfache Operationen schneller schlagen. ExactImage ist weniger leistungsfähig als ImageMagick, aber viel schneller, obwohl es nicht über PHP verfügbar ist, müssen Sie es auf dem Server installieren und ausführen
exec
.quelle
Für größere Bilder verwenden Sie phpThumb () . So verwenden Sie es: http://abcoder.com/php/problem-with-resizing-corrupted-images-using-php-image-functions/ . Es funktioniert auch für große beschädigte Bilder.
quelle