Конвертировать ОЧЕНЬ большие 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 будет по спецификации.

https://github.com/MalcolmMcLean/babyxrc

Я бы предположил, что более эффективным и быстрым решением было бы просто получить больше оперативной памяти - 128 ГБ не слишком дорого в наши дни (или добавить пространство подкачки).

Другие вопросы по тегам