149

Говорят, что файлы PNG используют сжатие без потерь. Однако всякий раз, когда я нахожусь в редакторе изображений, таком как GIMP, и пытаюсь сохранить изображение в виде файла PNG, он запрашивает параметр сжатия, который находится в диапазоне от 0 до 9. Если у него есть параметр сжатия, который влияет на визуальную точность сжатого изображения, как он делает PNG без потерь?

Я получаю поведение без потерь, только когда я установил параметр сжатия на 9?

7 ответов7

212

PNG сжат, но без потерь

Уровень сжатия представляет собой компромисс между размером файла и скоростью кодирования / декодирования. Чтобы чрезмерно обобщить, даже неформатные форматы, такие как FLAC, имеют схожие концепции.

Различные уровни сжатия, один и тот же декодированный выход

Хотя размеры файлов различны, из-за разных уровней сжатия фактический декодированный вывод будет идентичен.

Вы можете сравнить MD5 хэши декодированных выходов с ffmpeg используя MD5 muxer.

Лучше всего это показать на нескольких примерах:

Создать PNG-файлы:

$ ffmpeg -i input -vframes 1 -compression_level 0 0.png
$ ffmpeg -i input -vframes 1 -compression_level 100 100.png
  • По умолчанию ffmpeg будет использовать -compression_level 100 для вывода PNG.

Сравнить размер файла:

$ du -h *.png
  228K    0.png
  4.0K    100.png

Расшифруйте файлы PNG и покажите хеши MD5:

$ ffmpeg -loglevel error -i 0.png -f md5 -
3d3fbccf770a51f9d81725d4e0539f83

$ ffmpeg -loglevel error -i 100.png -f md5 -
3d3fbccf770a51f9d81725d4e0539f83

Поскольку оба хэша одинаковы, вы можете быть уверены, что декодированные выходы (несжатое, необработанное видео) абсолютно одинаковы.

180

PNG без потерь. GIMP, скорее всего, просто не использует лучшее слово в этом случае. Думайте об этом как о "качестве сжатия", или, другими словами, "уровне сжатия". При более низком сжатии вы получаете файл большего размера, но на его создание уходит меньше времени, а при более высоком сжатии вы получаете файл меньшего размера, на создание которого уходит больше времени. Как правило, вы получаете убывающую отдачу (т.е. не столько уменьшение размера по сравнению с увеличением времени, которое требуется) при переходе на самые высокие уровни сжатия, но это зависит от вас.

24

Сжатие PNG происходит в два этапа.

  1. Предварительное сжатие переупорядочивает данные изображения так, чтобы они были более сжимаемыми с помощью алгоритма сжатия общего назначения.
  2. Фактическое сжатие выполняется DEFLATE, который ищет и удаляет дублирующиеся последовательности байтов, заменяя их короткими токенами.

Поскольку шаг 2 требует очень много времени / ресурсов, базовая библиотека zlib (инкапсуляция необработанного DEFLATE) принимает параметр сжатия в диапазоне от 1 = быстрое сжатие, 9 = наилучшее сжатие, 0 = отсутствие сжатия. Отсюда и диапазон 0-9, и GIMP просто передает этот параметр в zlib. Заметьте, что на уровне 0 ваш png будет немного больше, чем эквивалентное растровое изображение.

Тем не менее, 9-й уровень - это только "лучшее", которое попытается использовать zlib, и все еще остается компромиссным решением.
Чтобы действительно почувствовать это, если вы готовы потратить в 1000 раз больше вычислительной мощности на исчерпывающий поиск, вы можете увеличить плотность данных на 3-8%, используя zopfli вместо zlib.
Сжатие по-прежнему без потерь, это просто более оптимальное представление данных DEFLATE. Это приближается к пределам zlib-совместимых библиотек и, следовательно, является истинным "лучшим" сжатием, которого можно достичь с помощью PNG.

16

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

PNG использует двухэтапный процесс сжатия:

  1. Предварительное сжатие: фильтрация (прогноз)
  2. Сжатие: DEFLATE (см. Википедию)

Этап предварительного сжатия называется фильтрацией, которая представляет собой метод обратимого преобразования данных изображения, чтобы основной механизм сжатия мог работать более эффективно.

В качестве простого примера рассмотрим последовательность байтов, равномерно увеличивающуюся от 1 до 255:

1, 2, 3, 4, 5, .... 255

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

1, 1, 1, 1, 1, .... 1

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

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

образ

Алгоритм работает с байтами, но для больших пикселей (например, 24-битный RGB или 64-битный RGBA) сравниваются только соответствующие байты, что означает, что красные компоненты цветов пикселей обрабатываются отдельно от зеленого и синего компонентов пикселей.

Чтобы выбрать лучший фильтр для каждой строки, кодировщик должен проверить все возможные комбинации. Это явно невозможно, так как даже 20-строчное изображение потребовало бы тестирования более 95 триллионов комбинаций, где "тестирование" включало бы фильтрацию и сжатие всего изображения.

Уровни сжатия обычно определяются как числа от 0 (нет) до 9 (наилучшее). Они относятся к компромиссам между скоростью и размером и относятся к тому, сколько комбинаций фильтров строк нужно попробовать. Нет никаких стандартов в отношении этих уровней сжатия, поэтому у каждого редактора изображений могут быть свои собственные алгоритмы того, сколько фильтров следует использовать при оптимизации размера изображения.

Уровень сжатия 0 означает, что фильтры вообще не используются, что быстро, но расточительно. Более высокие уровни означают, что в строках изображений пробуется все больше и больше комбинаций, и сохраняются только лучшие.

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

В дополнение к фильтрам уровень сжатия может также влиять на уровень сжатия zlib, который представляет собой число от 0 (без Deflate) до 9 (максимальное Deflate). То, как указанные уровни 0-9 влияют на использование фильтров, которые являются основной функцией оптимизации PNG, все еще зависит от разработчика инструмента.

Вывод состоит в том, что PNG имеет параметр сжатия, который может значительно уменьшить размер файла без потери даже одного пикселя.

Источники:

Wikipedia Портативная сетевая графика
Документация libpng Глава 9 - Сжатие и фильтрация

5

Хорошо, я опоздал на награду, но вот мой ответ в любом случае.

PNG всегда без потерь. Он использует алгоритм Deflate/Inflate, аналогичный тем, которые используются в программах zip.

Алгоритм Deflate ищет повторяющиеся последовательности байтов и заменяет их тегами. Параметр уровня сжатия указывает, сколько усилий программа использует для поиска оптимальной комбинации байтовых последовательностей, и сколько памяти зарезервировано для этого. Это компромисс между временем и использованием памяти и размером сжатого файла. Тем не менее, современные компьютеры настолько быстры и имеют достаточно памяти, поэтому редко приходится использовать другие параметры, отличные от самого высокого уровня сжатия.

Многие реализации PNG используют библиотеку zlib для сжатия. У Zlib девять уровней сжатия, 1-9. Я не знаю внутренностей Gimp, но так как он имеет настройки уровня сжатия 0-9 (0 = нет сжатия), я бы предположил, что этот параметр просто выбирает уровень сжатия zlib.

Алгоритм Deflate - это алгоритм сжатия общего назначения, он не предназначен для сжатия изображений. В отличие от большинства других форматов файлов изображений без потерь, формат PNG этим не ограничивается. Сжатие PNG использует то, что мы сжимаем 2D-изображение. Это достигается с помощью так называемых фильтров.

(Фильтр на самом деле немного вводит в заблуждение термин здесь. На самом деле он не меняет содержимое изображения, он просто кодирует его по-другому. Более точное название будет дельта-кодировщик.)

Спецификация PNG определяет 5 различных фильтров (в том числе 0 = нет). Фильтр заменяет абсолютные значения пикселей на отличие от предыдущего пикселя влево, вверх, по диагонали или их комбинации. Это может значительно улучшить степень сжатия. Каждая строка сканирования на изображении может использовать разные фильтры. Кодировщик может оптимизировать сжатие, выбирая лучший фильтр для каждой строки.

Подробнее о формате файла PNG см. В разделе « Спецификация PNG».

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

Программа командной строки pngcrush пробует несколько стратегий, чтобы найти лучший результат. Это может значительно уменьшить размер файла PNG, созданного другими программами, но это может занять довольно много времени на больших изображениях. См. Source Forge - pngcrush.

3

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

Конечно, компрессоры без потерь НИКОГДА не могут гарантировать фактическое сжатие. Случайные данные несжимаемы, шаблонов для поиска нет и сходства нет. Теория информации Шеннона и все такое. Весь смысл сжатия данных без потерь состоит в том, что люди обычно работают с весьма неслучайными данными, но для передачи и хранения мы можем сжать их до как можно меньшего числа бит. Надеюсь вплоть до максимально приближенной к колмогоровской сложности оригинала.

Будь то обычные данные в формате zip или 7z, изображения png, аудио flac или видео h.264 (в режиме без потерь), это одно и то же. При использовании некоторых алгоритмов сжатия, таких как lzma (7zip) и bzip2, запуск настройки сжатия приведет к увеличению времени ЦП DECODER (bzip2) или чаще всего необходимого объема оперативной памяти (lzma и bzip2 и h.264 с большим количеством опорных кадров). , Часто декодер должен сохранять больше декодированного вывода в ОЗУ, поскольку декодирование следующего байта может относиться к байту, декодированному много мегабайт назад (например, видеокадр, который наиболее похож на кадр с полсекунды назад, будет закодирован со ссылками на 12 кадров назад). ). То же самое с bzip2 и выбором большого размера блока, но это также распаковывает медленнее. У lzma есть словарь переменного размера, и вы можете создавать файлы, для декодирования которых требуется 1,5 ГБ ОЗУ.

0

Во-первых, PNG всегда без потерь. Очевидный парадокс связан с тем, что возможны два различных типа сжатия (для любого типа данных): с потерями и без потерь.

Сжатие без потерь сжимает данные (то есть размер файла), используя различные приемы, сохраняя все и не прибегая к каким-либо приближениям. В результате, возможно, что сжатие без потерь вообще не сможет сжимать вещи вообще. (Технически данные с высокой энтропией могут быть очень трудными или даже невозможными для сжатия без потерь.) Сжатие с потерями аппроксимирует реальные данные, но аппроксимация несовершенна, но такое "отбрасывание" точности позволяет обычно лучше сжать.

Вот тривиальный пример сжатия без потерь: если у вас есть изображение, состоящее из 1000 черных пикселей, вместо того, чтобы хранить значение для черного 1000 раз, вы можете сохранить счетчик (1000) и значение (черный), сжимая таким образом 1000 пикселей ». изображение "всего на два номера. (Это грубая форма метода сжатия без потерь, называемого кодированием по длине прогона).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .