Я пытаюсь обработать каталог изображений JPEG (примерно 600+, от 50 000 до 500 тыс.), Используя PHP: GD для изменения размера и сохранения изображений, но я немного ударил в начале процесса. После правильной обработки всего 3 изображений (30K, 18K и 231K) я получаю размер разрешенной памяти 16777216 байт, израсходованный PHP Fatal error.
Я езжу на велосипеде по изображениям и вызывая код ниже:
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
функции imagedestroy
но, похоже, это не повлияло. Сценарий просто постоянно задыхается от строки кода imagecreatefromjpeg
.
Я проверил php.ini, и параметр memory_limit = 16M
кажется, что он держится правильно. Но я не могу понять, почему память заполняется. Не следует ли вернуть память обратно сборщику мусора? Я действительно не хочу увеличивать параметр memory_limit. Это кажется плохим обходным решением, которое потенциально может привести к увеличению количества проблем в будущем.
FYI: Я запускаю свой сценарий из командной строки. Он не должен влиять на функциональность, но может повлиять на ваш ответ, поэтому я подумал, что должен упомянуть об этом.
Может ли кто-нибудь увидеть, если я просто пропущу что-то простое или если здесь есть недостаток дизайна? Вы думаете, что это будет довольно простая задача. Конечно, это должно быть возможно, не так ли?
ini_set('memory_limit', '64M');
задача решена
Возможно, что одно или несколько ваших изображений действительно раздуваются до 16M в необработанной памяти. Один из способов проверить – открыть его в Photoshop или Irfanview и проверить цветовое пространство и размеры пикселей.
Не нужно многого достичь 16M, например, рассмотрите «скромную» 6-мегапиксельную камеру. Он создает изображение размером 3072 пикселя на 2048 пикселей. В байте за цвет (RGB) размер необработанного файла:
3072 х 2048 х 3 = 18 874 368
Таким образом, вы можете увеличить объем памяти в соответствии с самыми большими изображениями, которые вы ожидаете обработать. Но вы должны учитывать их необработанный размер.
В некоторых случаях вы просто не можете ожидать наивысшего распределения памяти, которое потребуется для изображений, которые вы собираетесь обработать. Чтобы предотвратить сбой, вы можете включить следующие команды до и после цикла:
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 ()» код, который будет обрабатывать сбой.
Просто используйте ini_set();
и установите memory_limit на любой размер, который вы хотите.