Магия изображения / PHP падает с большими изображениями - PullRequest
4 голосов
/ 06 декабря 2010

У меня есть скрипт PHP, который используется для изменения размера изображений в папке FTP пользователя для использования на его веб-сайте.

Несмотря на медленное изменение размера, скрипт завершил корректно со всеми изображениями в прошлом. Однако недавно пользователь загрузил альбом изображений JPEG с разрешением 21 мегапикселя, и, как я обнаружил, сценарий не может преобразовать изображения, но не выдает никаких ошибок PHP. Когда я просматривал различные журналы, я обнаружил, что несколько процессов Apache были завершены с ошибками Out Of Memory.

Функциональная часть скрипта PHP - это, по сути, цикл for, который перебирает мои изображения на диске и вызывает метод, который проверяет, существует ли миниатюра, а затем выполняет следующее:

$image = new Imagick();
$image->readImage($target);
$image->thumbnailImage(1000, 0);
$image->writeImage(realpath($basedir)."/".rescale."/".$filename);
$image->clear();
$image->destroy();  

Сервер имеет 512 МБ оперативной памяти, обычно не менее 360 МБ + свободной.

В PHP ограничение памяти установлено на 96 МБ, но я уже устанавливал его выше без какого-либо влияния на проблему.
По моим оценкам, 21-мегапиксельное изображение должно занимать область 80 МБ + в несжатом виде, и поэтому я озадачен, почему ОЗУ так быстро исчезает, если объекты Image Magick не удаляются из памяти.

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

Приветствия

Ответы [ 3 ]

6 голосов
/ 11 октября 2012

См. этот ответ для более подробного объяснения.

imagick использует общую библиотеку, и ее использование памяти недоступно для PHP, поэтому настройка памяти PHPи сборка мусора не поможет.

Попробуйте добавить это до создания объекта new Imagick():

// pixel cache max size
IMagick::setResourceLimit(imagick::RESOURCETYPE_MEMORY, 32);
// maximum amount of memory map to allocate for the pixel cache
IMagick::setResourceLimit(imagick::RESOURCETYPE_MAP, 32);

Это приведет к переключению imagick на диск (по умолчанию / tmp), когдадля манипулирования изображениями требуется более 32 МБ.Это будет медленнее, но не будет исчерпано ОЗУ (если / tmp не находится на виртуальном диске, в этом случае вам нужно изменить место, где imagick записывает свои временные файлы).

4 голосов
/ 01 апреля 2016

MattBianco почти верен, единственное изменение состоит в том, что пределы памяти указаны в байтах, поэтому будет 33554432 для 32 МБ:

// pixel cache max size
IMagick::setResourceLimit(imagick::RESOURCETYPE_MEMORY, 33554432);
// maximum amount of memory map to allocate for the pixel cache
IMagick::setResourceLimit(imagick::RESOURCETYPE_MAP, 33554432);
2 голосов
/ 06 декабря 2010

Позвоните $image->setSize() до $image->readImage(), чтобы libjpeg изменил размер изображения при загрузке, чтобы уменьшить использование памяти.

(edit) , пример использования: Эффективное изменение размера изображения JPEGв PHP

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...