Конвертировать ОЧЕНЬ большие ppm файлы в JPEG/JPG/PNG?
Поэтому я написал программу на C++, которая производит изображения с очень высоким разрешением (фракталы). Я использую fstream, чтобы сохранить все данные в файле.ppm.
Все работает нормально, но когда я вхожу в действительно высокое разрешение (38400x21600) файл ppm имеет ~8 гигабайт. Однако с моими 16 гигабайтами памяти я все еще не могу преобразовать эту картинку. Я скачал пару конвертеров, но они не справились. Даже Gimp потерпел крах, когда я пытаюсь "экспортировать как...".
Итак, кто-нибудь знает хороший конвертер, который может обрабатывать действительно большие файлы ppm? На самом деле, я даже хочу превысить 100 гигабайт. Мне все равно, если это медленно, это должно просто работать.
Если такого конвертера нет: есть ли способ улучшить std::ofstream? Как, может быть, есть ли библиотека, которая автоматически создает файл PNG?
Спасибо за помощь!
Изменить: также я спросил себя, какой может быть лучший формат для сохранения этих больших изображений. Я исследовал, и JPEG выглядит довольно симпатично (маленький размер, все еще хорошего качества). Но может быть там лучший формат? Дай мне знать. Спасибо
3 ответа
Несколько мыслей...
8-битный файл PPM размером 38400x21600 должен занимать 2,3 ГБ. 16-битный файл PPM тех же размеров требует вдвое больше, то есть 4,6 ГБ, поэтому я не уверен, откуда у вас 8 ГБ.
VIPS отлично подходит для обработки больших изображений, и если я возьму файл PPM размером 38400x21600 и использую следующую команду в терминале (то есть в командной строке), я вижу, что он достигает пика в 58 МБ ОЗУ для преобразования из PPM в JPEG...
vips jpegsave fractal.ppm fractal.jpg --vips-leak
memory: high-water mark 58.13 MB
Это занимает 31 секунду на разумной спецификации iMac и производит файл размером 480 МБ из моих (случайных) данных, поэтому вы ожидаете, что ваш результат будет намного меньше, поскольку мой довольно несжимаем.
ImageMagick, с другой стороны, занимает пиковый рабочий набор памяти объемом 1,1 ГБ и выполняет такое же преобразование за 74 секунды:
/usr/bin/time -l convert fractal.ppm fractal.jpg
73.81 real 69.46 user 4.16 sys
11616595968 maximum resident set size
0 average shared memory size
0 average unshared data size
0 average unshared stack size
4051124 page reclaims
4 page faults
0 swaps
0 block input operations
106 block output operations
0 messages sent
0 messages received
0 signals received
9 voluntary context switches
11791 involuntary context switches
Перейдите к компилятору ресурсов Baby X и загрузите кодировщик JPEG, savejpeg.c. Требуется буфер RGB, который должен быть плоским в памяти. Взломайте его и замените версией, которая принимает поток 16x16 блоков. Затем напишите свой собственный загрузчик ppm, который загружается с полосой высотой 16 пикселей за раз.
Теперь система будет масштабироваться до огромных изображений, которые не помещаются в памяти. Как вы собираетесь их показывать, я не знаю. Но JPEG будет по спецификации.
Я бы предположил, что более эффективным и быстрым решением было бы просто получить больше оперативной памяти - 128 ГБ не слишком дорого в наши дни (или добавить пространство подкачки).