Основной мотивацией для формата PNG было создание замены для GIF, которая была бы не только бесплатной, но и улучшала ее по существу во всех отношениях. В результате сжатие PNG полностью без потерь, то есть исходные данные изображения могут быть восстановлены точно, бит за битом - как в GIF и большинстве форм TIFF.
PNG использует двухэтапный процесс сжатия:
- Предварительное сжатие: фильтрация (прогноз)
- Сжатие: 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 - Сжатие и фильтрация