Основной мотивацией для формата 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 Portable Network Graphics
документация libpng Глава 9 - Сжатие и фильтрация