PHP Image Resize optimieren?

chris4712

Erfahrenes Mitglied
Hallo!

Ich habe im Moment mit einer etwas schwierigen Kunden zu kämpfen. Für diese habe ich ein Skript gebaut, mit dem sie Bilder hochladen kann, diese werden automatisch verkleinert, und dann in eine Galerie zugeordnet.

Das funktioniert, bis zu einer gewissen Bildgröße, auch wunderbar. Jedoch meint diese Dame dass auch unbedingt Bilder mit 10MegaPixel verarbeitet werden müssen.

Und da steigt das Skript, an der Stelle wo die Bilder verkleinert werden, mit folgendem Fehler aus:
Code:
Fatal error: Out of memory (allocated 32768000) (tried to allocate 13056 bytes) in .....

Den Grund für den Fehler habe ich nach kurzer Suche im Internet gefunden. Es wird einfach zu viel Arbeitsspeicher verwendet.
Eine Lösung auch:
Code:
ini_set("memory_limit", "256M");
setzt den zu Verfügung gestellten Arbeitsspeicher auf 256MB hoch.
Leider klappt dies bei 1&1 nicht. Diese stellen nur 40MB - 8MB für irgendwas also 32MB zur Verfügung.

Gibt es irgendeine Möglichkeit diesen Code zu optimieren damit er auch mit größeren Bildern klar kommt?
PHP:
	function image_resize($source, $filename, $maxW, $maxH)
	{
		list($w, $h) = getimagesize($source); // Größe auslesen

		if ($h >=	$w)	{
			$wn = round($w/($h/$maxH));
			$hn = $maxH;
		}
		else {
			$hn = round($h/($w/$maxW));
			$wn = $maxW;
		}
		$dst_img=ImageCreateTrueColor($wn,$hn);
		$src_img=ImageCreateFromJpeg($source);
		ImageCopyResampled($dst_img,$src_img,0,0,0,0,$wn,$hn,$w,$h);
		imagejpeg($dst_img, $filename); // Ausgabe
		
		// Löscht die temporär erstellten Bilder
		imagedestroy($src_img);
		imagedestroy($dst_img);
	}

Ein Providerwechsel geht leider nicht. Es muss bei 1&1 bleiben.

Grüße!
 
item: ev. braucht imagecopyresized() weniger Speicher. Ein Versuch ists Wert.
item: Nimm mal imagedestroy($src_img); direkt nach dem imagecopyresized(). Also vor die Ausgabe von $dst_img
 
Hallo!

Erst einmal Danke für die Ideen!
item: ev. braucht imagecopyresized() weniger Speicher. Ein Versuch ists Wert.
Hat leider aber nix gebracht. Der Fehler tritt schon weiter vorne bei $src_img=ImageCreateFromJpeg($source); auf.
item: Nimm mal imagedestroy($src_img); direkt nach dem imagecopyresized(). Also vor die Ausgabe von $dst_img
Das hab ich auch mal gemacht. Naja, siehe oben ;)

Noch ne gute Idee?
 
Da wirds nichts draus werden, die Image-Funktionen brauchen soviel Speicher wie sie brauchen, abhängig vom Bild. Da kann man nix optimieren. Da hilft nur eins: Kleinere Bilder bzw. eine Obergrenze. Evtl kannst du das mit getimagesize() vorher schon abfangen.
 
Man könnte das Bild auch in kleinere Teile zerlegen, speichern und diese nacheinander dann verkleinern.

Um darauf zurückzukommen:
Ich habe gerade mal eine Funktion geschrieben, die das Bild in kleine Teile zerlegt:
PHP:
function SplitImage($img, $output_folder, $split_width, $split_height, $output_format=IMG_FORMAT_JPG, $output_quality=100)
{
  $x = 0;
  $y = 0;
  $width = imagesx($img);
  $height = imagesy($img);
  for ($y=0; $y<($height/$split_height); $y++)
  {
    for ($x=0; $x<($width/$split_width); $x++)
    {
      $img_part = imagecreate($split_width, $split_height);
      imagecopy($img_part, $img, 0, 0, $x*$split_width, $y*$split_height, $split_width, $split_height);
      
      if ($output_format==IMG_FORMAT_JPG)
        imagejpeg($img_part, $output_folder.DIRECTORY_SEPARATOR."part_".(($x+1)*($y+1)).".jpg", $output_quality);
      else if ($output_format==IMG_FORMAT_PNG)
        imagejpeg($img_part, $output_folder.DIRECTORY_SEPARATOR."part_".(($x+1)*($y+1)).".png", $output_quality);
      else if ($output_format==IMG_FORMAT_GIF)
        imagejpeg($img_part, $output_folder.DIRECTORY_SEPARATOR."part_".(($x+1)*($y+1)).".gif");
      
      imagedestroy($img_part);
    }
  }
}

Beispiel:
PHP:
$img = imagecreatefromjpeg("original.jpg");

SplitImage($img, "parts", 100, 100, IMG_FORMAT_PNG, 0);

imagedestroy($img);
 
Hallo!

Die Idee von ComFreek geht wohl leider nicht. Wie saftmeister schon schrieb müsste dann imagecreate... laufen, was aber schon nicht geht, da der Server bei ImageCreateFromJpeg($source) aussteigt.
Was mich beruhigt: Es gibt noch sehr viele, die das Problem haben (siehe z.B. http://www.code-styling.de/deutsch/memory-limit-das-leidige-thema-bei-1und1)

Die Lösung von CPoly find ich geil!! Würde ich am liebsten grade so einbauen, aber das passt im Moment gar nicht in mein aktuelles Konzept:
1) Bild hochladen
2.1) Nachschauen ob es dieses Bild schon mal gibt (anhand von RGB Code)
2.2) Wenn 2.1 nicht zutrifft, werden Stichpunkte für das Bild vergeben (um es später suchen zu können), das Aufnahmedatum kann eingegeben werden, und das Bild kann X-Beliebigen Galerien zugeordnet werden.
Da fehlt mir im Moment noch die Idee wie ich das bei Plupload machen könnte.
Grüße!
 
Schieb doch das Bild auf einen Server von Dir lass es da bearbeiten und schick es zurück.., gegen nee monatliche Miete versteht sich.., wer was "ausgefallenes" haben will muß eben dafür zahlen ;)

mfg
 
Zurück