PHP GD допустимый объем памяти исчерпан - PullRequest
10 голосов
/ 13 мая 2010

Я пытаюсь обработать каталог изображений JPEG (примерно 600+, в диапазоне от 50k до 500k), используя 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, но, похоже, это не оказало никакого влияния. Сценарий просто постоянно задыхается в строке кода imagecreatefromjpeg.

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

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

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

Ответы [ 4 ]

17 голосов
/ 13 мая 2010
ini_set('memory_limit', '64M');

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

13 голосов
/ 13 мая 2010

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

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

3072 x 2048 x 3 = 18 874 368

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

1 голос
/ 31 марта 2016

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

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 () "код, который будет обрабатывать сбой.

0 голосов
/ 21 августа 2010

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

...