Paul: Bild erzeugen: memory exhaust

Hallo zusammen,

ich habe ein kleines Problem. Ich möchte ein Verzeichnis durchgehen und in diesem alle Bilder verkleinern und an einem anderen Ort speichern. Soweit kein Problem. Ich habe ein Skript, das auch funktioniert. Aber nur beim ersten Bild. Sobald das 2. Bild estellt werden soll, bricht er ab:

hallo3! hallo4! hallo8! hallo11! Grafik../../fotos/DSC01059.JPGerzeugt hallo3! hallo4!

Fatal error: Allowed memory size of 12582912 bytes exhausted (tried to allocate 8192 bytes) in verzeichniswodasuploadskriptliegt/upload6.php on line 101

Die betreffende Zeile im Skript ist: $src = imagecreatefromjpeg($file_name_src);

Wie gesagt, das erste Bild geht sofort durch und ist auch da, wo es sein soll, beim zweiten Durchlauf scheitersts. Meine verzweifelte Frage: warum?

Bin für jede Hilfe dankbar, Gruß, paul.

Hier noch das komplette Skript, auch wenn alle relevanten Teile oben schon stehen sollten:

<?php $verzeichnis = '../../fotos/zip'; $verzeichnisneu = '../../fotos'; $inhalt=opendir($verzeichnis); $i = 0; $bilder;

function getImagesFromPath($path)          {          $result = array();

$handle=opendir($path);

while ($file = readdir ($handle))                {                if ($file != "." && $file != "..")                   {                   if (! is_dir($file))                      {                      $tmp = strtolower($file);                      $sub = substr($tmp, -4);                      if ($sub == ".png" || $sub == ".jpg" || $sub == ".gif" || $sub == ".bmp")                      $result[] = $file;                      }                   }                }          return $result;          }

function resizeImage($file_name_src, $file_name_dest, $width=159, $height = 80, $quality=100)                     {                     if (file_exists($file_name_src)  && isset($file_name_dest))                        {

if ($width == 0 && $height == 0)                           {                           echo 'hallo0!<br>';                           return false;                           }

$est_src = pathinfo(strtolower($file_name_src));                        $est_dest = pathinfo(strtolower($file_name_dest));

$size = getimagesize($file_name_src);

if   ($height && ! $width)                             {                             $h = number_format($height, 0, ',', '');                             $w = number_format(($size[0]/$size[1])$height,0,',','');                             echo 'hallo1!<br>';                             }                        else if (! $height && $width)                                {                                $w = number_format($width, 0, ',', '');                                $h = number_format(($size[1]/$size[0])$width,0,',','');                                echo 'hallo2!<br>';                                }                        else {                             $h = number_format($height, 0, ',', '');                             $w = number_format($width, 0, ',', '');                             echo 'hallo3!<br>';                             }

if ($est_dest['extension'] == "gif" || $est_dest['extension'] == "jpg")                           {                           echo 'hallo4!<br>';                           $file_name_dest = substr_replace($file_name_dest, 'jpg', -3);                           $dest = imagecreatetruecolor($w, $h);                           imageantialias($dest, TRUE);                           }                        elseif ($est_dest['extension'] == "png")                               {                               $dest = imagecreatetruecolor($w, $h);                               imageantialias($dest, TRUE);                               echo 'hallo5!<br>';                               }                        else   {                               echo 'hallo6!<br>';                               return FALSE;                               }

switch($size[2])                              {                              case 1:      //GIF                              $src = imagecreatefromgif($file_name_src);                              echo 'hallo7!<br>';                              break;                              case 2:      //JPEG                              $src = imagecreatefromjpeg($file_name_src);                              echo 'hallo8!<br>';                              break;                              case 3:      //PNG                              $src = imagecreatefrompng($file_name_src);                              echo 'hallo9!<br>';                              break;                              default:                              echo 'hallo10!<br>';                              return FALSE;                              break;                              }                       imagecopyresampled($dest, $src, 0, 0, 0, 0, $w, $h, $size[0], $size[1]);

switch($size[2])                             {                             case 1:                             case 2:                             imagejpeg($dest,$file_name_dest, $quality);                             echo 'hallo11!<br>';                             break;                             case 3:                             echo 'hallo12!<br>';                             imagepng($dest,$file_name_dest);                             }                       imagedestroy($dest);                       return TRUE;                       }                     return FALSE;                     }

$source = $verzeichnis; $data = getImagesFromPath($source); $width = 150; $height = 80;

if (!$data)    {    echo 'Mist!<br>';    }

foreach($data as $name)        {        $in  = $verzeichnis."/".$name;        $out = $verzeichnisneu."/".$name;        $ret = resizeImage($in, $out, $width, $height, $quality);        if   ($ret)             echo 'Grafik'.$out.'erzeugt<br>';        else echo "<font color='#FF0000'>Grafik $out konnte nicht erzeugt werden</font><br>\n";        } ?>

  1. Moin!

    Fatal error: Allowed memory size of 12582912 bytes exhausted (tried to allocate 8192 bytes) in verzeichniswodasuploadskriptliegt/upload6.php on line 101

    Nun, offenbar ist entweder das einzulesende Bild so riesig groß (es wird ja unkomprimiert in den Speicher getan), dass PHP mehr als erlaubt benötigen würde, oder dein erstes Bild liegt noch im Speicher rum und füllt ihn.

    Rechne also mal nach: Welche Auflösung hat das zweite Bild? Multipliziere X * Y * 3, und wenn dabei mehr als 12582912 rauskommt, dann ist es für deine PHP-Einstellungen zu groß.

    Andernfalls solltest du über den Einsatz von imagedestroy() für alle Bildressourcen nachdenken, die du für einen Durchlauf so eröffnest.

    - Sven Rautenberg

    1. Hallo Sven,

      hmm, die Testbilder haben alle um die 23k, ich dachte das waere die Groesse. Das Bild wird ja unten wieder mit imagedestroy zerstoert, muesste also wieder weg sein. Komisch ist dann nur, warum der Fehler erst beim 2. Bild auftritt.

      Gruss, Paul.

      1. hi,

        hmm, die Testbilder haben alle um die 23k, ich dachte das waere die Groesse.

        ja, komprimiert vermutlich, als jpeg o.ä.

        um ein bild bearbeiten zu können, muss PHP es aber natürlich intern entpacken - und dann kommst du, bei einem true color bild, wie Sven schon sagte, auf einen platzbedarf von X * Y * 3 Byte. (true color = 24 bit farbtiefe = drei byte pro pixel.)

        gruss,
        wahsaga

        1. hi,

          noch ne frage. ok, es lag am foto. aber ich hab mal nachgerechnet. 12582912 bytes geteilt durch 3 gibt 4194304 bytes. das sind dann die komponenten für x und y. macht nach adam riese beispielsweise 2000 mal 2000 px. und dann wär noch luft. meine fotos haben digicambedingt maximal 2048 x 1536 = 3145728. wär also auch noch dicke luft nach oben.  versteh ich da was falsch oder liegt der fehler doch woanders?

          gruß, paul

          1. Moin!

            noch ne frage. ok, es lag am foto. aber ich hab mal nachgerechnet. 12582912 bytes geteilt durch 3 gibt 4194304 bytes. das sind dann die komponenten für x und y. macht nach adam riese beispielsweise 2000 mal 2000 px. und dann wär noch luft. meine fotos haben digicambedingt maximal 2048 x 1536 = 3145728. wär also auch noch dicke luft nach oben.  versteh ich da was falsch oder liegt der fehler doch woanders?

            Der Rest vom Skript muß natürlich auch noch Platz haben. Und die Variablen. Mit Pech (ich hab mir die Begrenzung, und was da alles dazugezählt wird, noch nicht intensiv angeschaut) auch noch der Apache-Prozess und/oder das PHP-Modul.

            - Sven Rautenberg

      2. Moin!

        Hallo Sven,

        hmm, die Testbilder haben alle um die 23k, ich dachte das waere die Groesse.

        Wie wahsaga sagte: Die DATEIgröße ist nicht entscheidend. Ich habe schon JPG-Bilder gesehen, die als Datei 7 MB groß waren, unkomprimiert im Speicher aber über 200 MB!

        Das Bild wird ja unten wieder mit imagedestroy zerstoert, muesste also wieder weg sein.

        Du hast zwei Bilder im Speicher, nicht nur eines.

        Komisch ist dann nur, warum der Fehler erst beim 2. Bild auftritt.

        Beim zweiten Bild hast du schon DREI Bilder im Speicher. Zwei vom ersten Bild, eines davon wird gelöscht, plus zwei vom zweiten Bild (bzw. scheitert dein Skript beim Versuch, ein weiteres Bild hinzuzufügen).

        - Sven Rautenberg

        1. Hallo Ihr beiden,

          ok, ich glaub ich muß src auch noch zerstören. hab das auch gemacht und der fehler trat immer noch auf.

          hab andere fotos versucht, lief ohne probleme durch! danke also. nun meine frage: kann mein provider siese größe einstellen oder muß ich wirklich darauf achten, daß die fotos klein sind?

          danke im voraus!
          gruß, paul

          1. hi,

            nun meine frage: kann mein provider siese größe einstellen oder muß ich wirklich darauf achten, daß die fotos klein sind?

            natürlich _kann_ dein provider dieses limit heraufsetzen, wenn er möchte.
            wird er aber vermutlich nicht wollen, weil die ressourcen auf so einem server nun mal auch begrenzt sind - und wenn dann noch andere webseiten auf der gleichen maschine laufen (shared hosting), wird die luft ja recht schnell dünn, wenn jeder benutzer mehr als das "übliche" an speicher verbrauchen kann.

            gruss,
            wahsaga