Allowed memory size of 33554432 bytes exhausted (tried to allocate 2558 bytes)

Vidíte často tuto hlášku při zpracování obrázků? Možná nechápete proč, když zpracováváte obrázek o velikosti 500kb a máte memory_limit 16M. A chcete vědět jak zabránit pádu skriptu nebo předejít vyřerpání paměti před operacemi s obrázky?


Proč se vyčerpá paměť při zpracování obrázku v PHP?

Problém je v tom, že při použití funkcí imagecreatefrompng, imagecreatefromjpg, imagecreatefromgif a další, php nejdříve zpracovávaný obrázek převede na nekomprimovaný a ten je mnohonásobně větší.

Přesto, že zpracováváte obrázek o velikosti 500kB můžete vyčerpat více než 32MB vaší povolené paměti pro php skripty. V takové situaci by bylo vhodné vypočítat potřebnou paměť pro zpracování obrázku a oznámit uživateli a skriptu, že tudy cesta nevede. Další možností je v takovém případě zvětšit velikost povoleného limitu paměti, ale na to pravděpodobně na většině hostingů nebudete mít právo.

Řešení je následující:

  1. $size=getimagesize($image);
  2. $memoryneed = round(($size[0] * $size[1] * $size['bits'] * $size['channels'] / 8 + pow(2, 16)) * 1.65);
  3. if (function_exists('memory_get_usage') && ((memory_get_usage() + $memoryneed) > ((integer)ini_get('memory_limit') * pow(1024, 2)))) {
  4. ...zpracovat takovýto obrázek nebude možné, měli bychom vyhodit upozornění a zastavit skript...
  5. ...nebo můžeme nastavit limit paměti...
  6. ini_set('memory_limit', (integer) ini_get('memory_limit') + ceil(((memory_get_usage() + $memoryneed) - (integer) ini_get('memory_limit') * pow(1024, 2)) / pow(1024, 2)) . 'M');
  7. }