Bilder und Memory size exhausted
September 2009
Ein Problem, das oft auftritt, wenn man mit grossen Bildern in PHP arbeiten will, ist:
Normalerweise ist die Funktion imagecreatefromXYZ() daran schuld, das heisst das Bild, welches man laden will, ist zu gross.
Allerdings gibt es eine Möglichkeit, den vom Bild benötigten Speicherplatz auszurechnen. Es ist zwar nicht exakt, doch lässt sich die Fehlermeldung meist im Voraus erkennen.
Die Formel lautet: (nach einem Benutzerkommentar aus dem PHP-Manual)
Mittels getimagesize() holen wir uns die benötigten Informationen der Datei.
Auf der anderen Seite kann man auch das memory_limit vergrössern, anstatt eine Fehlermeldung zu produzieren.
Bei der Zahl 10240 handelt es sich um 10 Kibibytes, welche als Puffer dienen sollten.
Siehe auch:
Idee von http://www.php.net/imagecreatefromjpeg#76968.
Fatal error: Allowed memory size of * bytes exhausted (tried to allocate * bytes) in * on line *
Normalerweise ist die Funktion imagecreatefromXYZ() daran schuld, das heisst das Bild, welches man laden will, ist zu gross.
Allerdings gibt es eine Möglichkeit, den vom Bild benötigten Speicherplatz auszurechnen. Es ist zwar nicht exakt, doch lässt sich die Fehlermeldung meist im Voraus erkennen.
Die Formel lautet: (nach einem Benutzerkommentar aus dem PHP-Manual)
Num bytes = Width * Height * Bytes per pixel * Overhead fudge factor
Mittels getimagesize() holen wir uns die benötigten Informationen der Datei.
<?php
$bild = 'http://pfad.zum/12/megapixel/bild.jpg';
# Informationen zum Bild holen
$info = getimagesize($bild);
switch($info['mime']){ // Faktor festlegen
case 'image/png': $overh = 5.05; break;
case 'image/gif': $overh = 0.69; break;
case 'image/jpeg': $overh = 1.69; break;
default: $overh = 1;
}
$info['channels'] = isset($info['channels']) ? $info['channels'] : 1;
# den durch das Bild benötigten Speicher berechnen
$memo_use_img = round($info[0] * $info[1] * $info['bits']/8 * $info['channels'] * $overh);
# memory_limit auslesen
$memo_limit = ini_get('memory_limit');
$unit = strtoupper(substr($memo_limit, -1));
$memo_limit = (int)$memo_limit;
switch($unit){
case 'G': $memo_lim *= 1024;
case 'M': $memo_lim *= 1024;
case 'K': $memo_lim *= 1024;
}
# wenn das Bild zu viel Speicher beanspruchen wird:
if(memory_get_usage()+$memo_use_img > $memo_limit){
$im = imagecreatetruecolor(220, 16);
$col = imagecolorallocate($im, 250, 0, 0);
$bg = imagecolorallocate($im, 255, 255, 255);
imagefilledrectangle($im, 0, 0, 220, 16, $bg);
// eine Fehlermeldung als Grafik darstellen
imagestring($im, 2, 3, 1, "Image will exceed PHP's memory_limit", $col);
header('Content-type: image/png');
imagepng($im); // Grafik ausgeben
imagedestroy($im);
exit; // Script abbrechen
}
# restliches Script
$img = imagecreatefromXYZ($bild);
// ...
?>
Wenn das Bild nun zu gross sein könnte, wird in diesem Falle eine kleine Ersatzgrafik mit einer Fehlermeldung ausgegeben. Wenn keine Grafik erscheinen soll, kann auch normaler Text ausgegeben werden.Auf der anderen Seite kann man auch das memory_limit vergrössern, anstatt eine Fehlermeldung zu produzieren.
<?php
ini_set('memory_limit', memory_get_usage()+$memo_use_img+10240);
?>
Diese Zeile wäre anstelle der Fehlermeldungsausgabe einzusetzen.Bei der Zahl 10240 handelt es sich um 10 Kibibytes, welche als Puffer dienen sollten.
Siehe auch:
Idee von http://www.php.net/imagecreatefromjpeg#76968.
