PHP Problem mit "memory limit"

MaxXx007

Cadet 3rd Year
Registriert
Jan. 2009
Beiträge
37
Hallo,

ich habe ein PHP-Script, was über swf-upload hochgeladene Bilder mit neuem Dateinamen in ein anderes Verzeichnis kopiert und dann noch ein Thumbnail von dem Bild erstellt. Beides funktioniert mit einer selbstgeschriebenen Funktion, der ich die gewünschte Größe des Bildes nach dem kopieren übergebe.

PHP:
function image_copy($img_src,     // Dateipfad
					$des_src,      //Zielverzeichnis
                    $img_width,   // max. Größe in x-Richtung
	                $img_height, // max. Größe in y-Richtung
				    $option = ""
				   )
{
    if ($option == "galleryimg") {
    	$img_width = "800";
    	$img_height = "800";
    }
    elseif ($option == "thumb")  {
		$img_width = "150";
		$img_height = "150";
	}
    $image = imagecreatefromjpeg($img_src);
    list($src_width, $src_height) = getimagesize($img_src);
    if($src_width >= $src_height)
    {
      $new_image_width = $img_width;
      $new_image_height = $src_height * $img_width / $src_width;
    }
    if($src_width < $src_height)
    {
      $new_image_height = $img_width;
      $new_image_width = $src_width * $img_height / $src_height;
    }
    $new_image = imagecreatetruecolor($new_image_width, $new_image_height);
    $return1 = imagecopyresampled($new_image, $image, 0, 0, 0, 0, $new_image_width,$new_image_height, $src_width, $src_height);
    $return2 = imagejpeg($new_image, $img_src, 100);
    imagedestroy($image);
	imagedestroy($new_image);
    if ($return1 && $return2) {
    	return true;
    }
}

im ausführenden Script wird die Funktion natürlich in einer foreach-schleife mehrmals aufgerufen,
jedoch kommt dann die Fehlermeldung:

Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 11264 bytes) in (...) /inc/function_admin.inc.php on line 479
(auf line 479 ist der Befehl aus der image_copy()-Funktion:
PHP:
$image = imagecreatefromjpeg($img_src);
)

ich verstehe nun aber überhaupt nicht wo das problem ist, keins der bilder ist größer als 16 mb, sie sind sogar alle kleiner 5 mb, und die bilder im speicher werden ja alle mit imagedestroy()-gelöscht.

Woher kommt dann der Fehler??

Hier noch mal der Code vom ausführenden Script:
PHP:
if (!empty($_POST['sort'])) {

		 $pfad = "../../images/gallerys/temp/$id/";
		 $sort = $_POST['sort'];
		 $handle = opendir($pfad);
		 $lv = 1;
		 while($file = readdir($handle)) {
		    // Serververweise nicht auslesen
		    if($file != "." && $file != "..") {
		        // Nur Bilder auslesen
		        if(preg_match("/.(jpg|gif|png)$/i", $file)) {
		            // Ausgelesene Bilder in ein Array laden
		            $bild[$lv] = $file;
		            $filen = explode(".", $file);
		            $filename[$lv] = $filen[0];
		            $lv++;
		        }
		    }
		 }
		 closedir($handle);
		 // Wieviele Bilder ?
		 $anzbilder = count($bild);
		 if ($sort == "chron") {

		 for ($i=1;$i<=$anzbilder;$i++) {

				 $exifpfad[$i] = $pfad.$bild[$i];
				 $exif[$i] = exifdatetime($exifpfad[$i], "one");
				 $bilder[$exif[$i]]=$bild[$i];
		 }
		 if (sort($exif)) {
		 	echo "Nach Datum sortiert<br>";
		 }
		 $j="1";
		 $x=0;
		 $y=0;
		 foreach ($exif as $date) {
			echo $date."&nbsp;";
			foreach($bilder as $date2 => $img){
			 	if ($date == $date2) {
			 		$image=$img;
			 	}

			 }
			if (strlen($j) == 1) $j = "00".$j;
			elseif (strlen($j) == 2) $j = "0".$j;

			echo $j."&nbsp;";
			$new = "/home/www/kunden/manos-dresden.de/NEU/images/gallerys/$id/";

			echo $image."<br>";
		 	if (image_copy($pfad.$image, $new.$j.".jpg", "", "", "galleryimg")) {
		 		$x++;
		 	}
		 	$fname = $j.".jpg";
		 	if (image_copy($new.$j.".jpg", $new."thumbs/".$j."jpg", "", "", "thumb")) {
				$y++;
		 	}
		 	$j++;
		 }

		 }
}


Vielen Dank für jede Hilfe,

Max
 
$new_image = imagecreatetruecolor($new_image_width, $new_image_height);
$return1 = imagecopyresampled($new_image, $image, 0, 0, 0, 0, $new_image_width,$new_image_height, $src_width, $src_height);
$return2 = imagejpeg($new_image, $img_src, 100);

Wieviele Bilder hast du zu dem Zeitpunkt im Speicher? :-) Kein Wunder, dass sich da der Server beschwert.
 
Hi,

das Problem an der Sache ist ja, dass du bei imagecreatefromjpeg dann mit der Bitmap-Version deiner Bilder arbeitest, sprich der ganze Spaß ist unkomprimiert. In diesem Fall sind dann 16MB relativ schnell ausgeschöpft. Vielleicht kannst du das Memory Limit ja mit ini_set etwas höher setzen?

Gruß,

Mathias
 
danke für die antworten,
dass der die bilder als zum verarbeiten ins bitmap-format umwandelt, wusste ich nicht.
das memory-limit kann ich nicht hochstellen, und ImageMagick hab ich anscheinend nicht zur verfügung, den wenn müsst ich es ja irgendwo in der ausgabe von phpinfo() finden oder?

hat jemand vielleicht eine idee wie ich das script umschreiben könnte, so dass ich die bilder auch ohne vielfaches laden in den momory verkleinern und verschieben kann?

Max
 
Du könntest eine automatische Weiterleitung (per HTML oder mittels header()) einbauen und immer nur z.B. 5 pro Aufruf bearbeiten.

An sich machst du es nämlich richtig mit dem imagedestroy() und daher kann man da wohl nicht allzu viel tun. Die Frage wäre auch ob da evtl. ein paar Bilder eine höhere Auflösung (bzw. letztlich mehr Pixel) haben und diese den Abbruch erzeugen. 800x800 Pixel (deine Ausgabe bei den großen Gallerybildern) brauchen ja schon 2,2MB unkomprimiert. Dazu brauchst du dann noch das Originalbild, Speicher zum Bearbeiten (resamplen) sowie eben Speicher für das restliche PHP-Skript so dass Bilder mit um die 4 Megapixel wahrscheinlich schon Probleme bereiten werden. Falls das so sein sollte und du wirklich so große Bilder umwandeln musst ist das in der beschriebenen Situation (ohne Imagemagick) wohl fast ein unlösbares Problem...
 
Zurück
Oben