2010-05-13 4 views
9

Я пытаюсь обработать каталог изображений JPEG (примерно 600+, от 50 000 до 500 тыс.), Используя PHP: GD для изменения размера и сохранения изображений, но я ударил немного Захватывают довольно рано в этом процессе. После правильной обработки всего 3 изображений (30K, 18K и 231K) я получаю Допустимый размер памяти 16777216 байт исчерпан PHP Неустранимая ошибка.PHP GD Допустимый размер памяти

Я на велосипеде через образы и вызывая код ниже:

list($w, $h) = getimagesize($src); 

    if ($w > $it->width) { 
     $newwidth = $it->width; 
     $newheight = round(($newwidth * $h)/$w); 
    } elseif ($w > $it->height) { 
     $newheight = $it->height; 
     $newwidth = round(($newheight * $w)/$h); 
    } else { 
     $newwidth = $w; 
     $newheight = $h; 
    } 

    // create resize image 
    $img = imagecreatetruecolor($newwidth, $newheight); 
    $org = imagecreatefromjpeg($src); 

    // Resize 
    imagecopyresized($img, $org, 0, 0, 0, 0, $newwidth, $newheight, $w, $h); 
    imagedestroy($org); 

    imagejpeg($img, $dest); 

    // Free up memory 
    imagedestroy($img); 

Я пытался освободить память с функцией imagedestroy но это, кажется, не имеют никакого влияния. Сценарий просто постоянно задыхается от строки кода imagecreatefromjpeg.

Я проверил php.ini, и настройка memory_limit = 16M кажется, что она держится правильно. Но я не могу понять, почему память заполняется. Не следует ли вернуть память обратно сборщику мусора? Я действительно не хочу увеличивать параметр memory_limit. Это кажется плохим обходным решением, которое потенциально может привести к увеличению количества проблем в будущем.

FYI: Я запускаю свой сценарий из командной строки. Он не должен влиять на функциональность, но может повлиять на ваш ответ, поэтому я подумал, что должен упомянуть об этом.

Может ли кто-нибудь увидеть, если я просто пропустил что-то простое или если здесь есть дефект дизайна? Вы думаете, что это будет довольно простая задача. Конечно, это должно быть возможно, не так ли?

ответ

15
ini_set('memory_limit', '64M'); 

проблема решена

+0

Я попробую. Я предполагаю, что это будет ошибка позже в этом процессе. Надеюсь, я ошибаюсь. – gurun8

+0

Я был неправ. Это сработало. Благодарю. – gurun8

+5

Я предполагаю, что должен был просто написать, что делать, а не зачем делать это. – JYelton

12

Возможно, что одно или несколько изображений на самом деле раздуваются до 16 М в необработанной памяти. Один из способов проверить - открыть его в Photoshop или Irfanview и проверить цветовое пространство и размеры пикселей.

Это не займет много времени, чтобы достичь 16M, например, рассмотреть «скромную» 6-мегапиксельную камеру. Он создает изображение размером 3072 пикселя на 2048 пикселей. При байтах на цвет (RGB) исходный размер:

3072 х 2048 х 3 = 18.874.368

Таким образом, вы можете увеличить объем памяти в соответствии с крупнейшими изображениями, которые вы ожидаете обрабатывать , Но вы должны учитывать их необработанный размер.

+0

Я проверю это. Благодарю. – gurun8

+3

И gd не только сохраняет три, но и четыре байта на пиксель ~ 25M – VolkerK

+0

Я предполагаю, что это альфа-канал? Хорошо, VolkerK. – JYelton

0

Просто используйте ini_set(); и установите memory_limit на любой размер вы хотите.

1

В некоторых случаях вы просто не можете ожидать наивысшего распределения памяти, которое потребуется для изображений, которые вы собираетесь обработать. Чтобы предотвратить аварию, вы можете включать в себя следующие команды до и после цикла:

register_shutdown_function ('my_function'); 
$mem_limit = ini_get ('memory_limit'); 
ini_set ('display_errors', false); 
ini_set ('memory_limit', '400M');   // some high value 

(... ваш процесс ...)

ini_set ('memory_limit',$mem_limit); 

и место в функции "my_function()" код, который будет обрабатывать аварии.

Смежные вопросы