Bilder und Memory size exhausted

September 2009

Ein Problem, das oft auftritt, wenn man mit grossen Bildern in PHP arbeiten will, ist:
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']/$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(22016);
  
$col imagecolorallocate($im25000);
  
$bg imagecolorallocate($im255255255);
  
imagefilledrectangle($im0022016$bg);
  
// eine Fehlermeldung als Grafik darstellen
  
imagestring($im231"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.
 


Andere Einträge