Изменение размера больших изображений с помощью ImageResizer и исключений нехватки памяти

Я сталкиваюсь с исключениями из памяти, когда я изменяю размер изображения 9000x9000 квадратных с помощью ImageResizer.Net (в 32-битной системе):

ImageBuilder.Current.Build(imageFileName, outputFileName, settings, true);

Однако я могу успешно изменить размер больших изображений с помощью потока:

using (var stream = new FileStream(imageFileName, FileMode.Open, FileAccess.Read))
using (var img = Image.FromStream(stream, true, false))
{
    ImageBuilder.Current.Build(img, outputFileName, settings);
    stream.Close();
}

но этот последний метод по-прежнему вызывает исключение нехватки памяти после x циклов. Есть ли огромная утечка памяти в ImageResizer или ошибка в моем коде?

В любом случае, есть ли обходной путь?


person MariaSnuggles    schedule 14.09.2013    source источник


Ответы (3)


Если вы собираетесь обрабатывать 81-мегапиксельные изображения, вам потребуется 64-разрядная система. Только для распаковки образа потребуется от 350 до 800 непрерывных мегабайт ОЗУ.

В 32-битной системе (даже с 16 ГБ оперативной памяти) для любого процесса .NET изначально доступно только 1200 МБ или около того. Из-за фрагментации (не утечки памяти!), эти 1200 МБ будут разбиты на небольшие куски по 50-100 МБ при любой активности. Поскольку вам нужна память блоками по 800 МБ (поскольку вы обрабатываете массивные изображения), это быстро перестает работать.

Чтобы позволить .NET бороться с фрагментацией памяти, вам нужно дать ему (а) время и (б) много дополнительного пространства.

В 64-разрядной системе процесс должен иметь доступ к достаточному объему оперативной памяти, чтобы среда выполнения .NET не голодала при этих рабочих нагрузках.

person Lilith River    schedule 14.09.2013
comment
К сожалению, на данном этапе разработки обновление до 64-битной машины невозможно. Запуск фотошопа и расширенное редактирование изображений возможно на машине, так что, может быть, мне следует искать неуправляемую библиотеку с оболочкой .net? - person MariaSnuggles; 14.09.2013
comment
Photoshop имеет собственную систему виртуальной оперативной памяти и специальный файл подкачки. Пейджинг на диск — это самый быстрый способ убить сервер, поэтому мы это запрещаем. Здесь вы боретесь с основными ограничениями. Даже libvips, вероятно, единственная библиотека, разработанная на основе заточенный под гигапиксельные изображения в условиях низкой оперативной памяти, будет плохо работать в этих условиях. - person Lilith River; 14.09.2013
comment
Ааа, на самом деле я использую ImageResizer как средство для вырезания, обрезки и изменения размера изображений для настольного приложения, поэтому подкачка не такая уж большая проблема, если она успешна! - person MariaSnuggles; 14.09.2013

Я бы подумал, что вы максимизируете свою оперативную память при изменении размера большого изображения (хотя не уверен).

Попробуйте использовать подключаемый модуль DiskCache: http://imageresizing.net/plugins/diskcache http://imageresizing.net/download

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

Мне жаль отвечать комментарием «попробуйте это» в качестве ответа, но я пока не могу писать комментарии из-за недостаточной репутации SO.

person Certs    schedule 14.09.2013
comment
Во-первых, я читаю и пишу непосредственно в файловую систему, что, по сути, то же самое, что и плагин дискового кеша? - person MariaSnuggles; 14.09.2013

Как упоминалось в комментарии Computer Linguist к своему собственному ответу, libvips может изменять размер больших изображений, используя (гораздо) меньше памяти. . [На самом деле я использовал версию для командной строки, так как не встретил никаких оболочек .NET для самой библиотеки.]

В моем случае изображение, которое я пытался изменить, имело размер 21 920 × 14 610 пикселей. ImageResizer успешно изменил размер версии изображения PNG (15+ МБ), но выдал OutOfMemoryException для версии JPEG (22+ МБ).

Я использую Windows 7 64-бит на компьютере с 8 ГБ оперативной памяти.

person Kenny Evitt    schedule 18.09.2014