UGLYPEAR AI обновил бизнес: высокопроизводительное сжатие документов × RAG-платформа инженерии данныхУзнать о новом направлении →

Принцип сжатия PNG: почему алгоритм DEFLATE без потерь?

Вывод вперёд: PNG — это сжатие без потерь, потому что он использует алгоритм DEFLATE — оба этапа, словарное сжатие LZ77 и кодирование Хаффмана, являются полностью обратимыми математическими операциями, после распаковки данные побайтово идентичны исходным. Процесс сжатия PNG: данные пикселей сначала проходят предсказание строк фильтрации для устранения избыточности между соседними пикселями, затем сжимаются алгоритмом DEFLATE. Скриншот UI 3000x2000: PNG сжимает исходные 17.2MB до 0.35MB, снижение на 97.9%, при этом значение каждого пикселя не меняется. Ниже подробно объясняется на двух уровнях: структура файла PNG и принцип алгоритма DEFLATE.

Если вы не очень знакомы с общими методами сжатия изображений, рекомендуется сначала прочитать Руководство по сжатию изображений: сравнение форматов JPG/PNG/WebP.

1. Структура файла PNG: как организованы данные

Файл PNG состоит из серии блоков данных (chunk), каждый chunk содержит четыре части: тип, длина, данные и контрольная сумма. Понимание роли этих chunk означает понимание внутренней структуры файла PNG.

Блок данныхПолное названиеФункцияОбязательностьТипичный размер
СигнатураPNG Signature8-байтовый идентификатор файла (89 50 4E 47 0D 0A 1A 0A)Обязательный8 байт
IHDRImage HeaderОсновная информация об изображении (ширина/высота/глубина цвета/тип цвета)Обязательный25 байт
IDATImage DataСжатые данные пикселей (кодирование DEFLATE)ОбязательныйПеременный (основной)
IENDImage EndМаркер конца файлаОбязательный12 байт
PLTEPaletteПалитра (режим индексированного цвета)Обязательный для индексированного цвета≤768 байт
tRNSTransparencyИнформация о прозрачностиНеобязательныйПеременный
tEXtTextТекстовые метаданные (автор/описание и т.д.)НеобязательныйПеременный
gAMAImage GammaИнформация о гамма-коррекцииНеобязательный16 байт

Самый важный chunk в файле PNG — это IDAT, он хранит данные пикселей после предсказания строк фильтрации и сжатия DEFLATE. Изображение 3000x2000 с 24-битным RGB, исходные данные пикселей около 17.2MB (3000x2000x3 байта), после сжатия PNG часть IDAT может быть всего 0.3-0.5MB. Эффект сжатия в основном зависит от повторяемости содержимого изображения — большие области однотонного цвета имеют самую высокую степень сжатия, фотографии с шумом — самую низкую.

2. Принцип алгоритма DEFLATE: двухэтапное сжатие LZ77+Хаффман

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

ЭтапАлгоритмПринципУстраняемая избыточностьОбратимость
Первый этапLZ77Поиск повторяющихся последовательностей байтов, замена ссылками (расстояние, длина)Избыточность повторяющихся последовательностейПолностью обратим
Второй этапКодирование ХаффманаЧастые данные — короткие коды, редкие данные — длинные кодыИзбыточность кодированияПолностью обратим

1. Словарное сжатие LZ77

LZ77 — это алгоритм словарного сжатия на основе "скользящего окна". Он поддерживает скользящее окно (обычно 32KB), в пределах окна ищет самую длинную последовательность байтов, совпадающую с текущей позицией. Если совпадение найдено, заменяет эту последовательность байтов ссылкой (расстояние, длина); если совпадения нет, выводит исходный байт.

Пример: предположим, в данных изображения есть непрерывные белые пиксели (RGB 255,255,255), повторяющиеся 1000 раз. LZ77 найдёт этот повторяющийся шаблон в окне, после записи первого триплета последующие 999 триплетов заменяются ссылкой "вернуться на 3 байта, скопировать 3 байта, повторить 999 раз". 3000 байт исходных данных сжимаются в последовательность из десятка байт ссылок, степень сжатия более 99%.

Характеристика данныхЭффект сжатия LZ77Типичная степень сжатияПричина
Большие области однотонного цветаОтличный95%+Длинные повторяющиеся последовательности, высокая эффективность замены ссылками
Горизонтальные градиентыХороший70%-85%Шаблоны градиентов могут совпадать
Регулярные текстурыХороший60%-80%Повторяющиеся текстуры могут быть заменены ссылками
Случайный шумПлохой0%-10%Нет повторяющихся последовательностей для совпадения
Естественные фотографииПлохой5%-20%Большая разница между пикселями, мало совпадений

2. Кодирование Хаффмана

Данные, выводимые LZ77 (смешанные ссылки и исходные байты), затем проходят кодирование Хаффмана. Основная идея кодирования Хаффмана: часто встречающиеся символы используют короткие коды, редкие — длинные коды, тем самым уменьшая среднюю длину кодирования.

Пример: если в выводе LZ77 "маркер ссылки" встречается с частотой 60%, исходное значение байта 255 — 20%, другие значения — по небольшому проценту. Хаффман назначит "маркеру ссылки" 2-битный код, значению 255 — 3-битный код, редким значениям — 8-12-битные коды. Таким образом средняя длина кодирования каждого символа снижается с фиксированных 8 бит до 3-4 бит, дальнейшее сжатие около 50%.

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

3. Механизм сжатия без потерь: фильтрация строк + DEFLATE

Сжатие PNG без потерь зависит не только от алгоритма DEFLATE, но и от ключевого этапа предварительной обработки — предсказания строк фильтрации (Filter). Этот этап выполняется перед DEFLATE, цель — сделать данные пикселей более подходящими для сжатия LZ77.

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

Тип фильтрацииНазваниеФормула предсказанияПрименимый сценарий
0NoneБез предсказания, исходное значениеДанные с нерегулярным шумом
1SubТекущее значение - левое значениеИзображения с горизонтальными градиентами
2UpТекущее значение - верхнее значениеИзображения с вертикальными градиентами
3AverageТекущее значение - (левое+верхнее)/2Изображения с плавными переходами
4PaethТекущее значение - предсказанное значение PaethУниверсальное (оптимально для большинства изображений)

Кодировщик PNG может независимо выбирать тип фильтрации для каждой строки. SmartSlim на основе собственного движка сжатия Rust пробует все 5 способов фильтрации для каждой строки и выбирает тот, который даёт наилучший эффект сжатия, это позволяет дополнительно уменьшить размер на 10%–20% по сравнению с фиксированным использованием одного способа фильтрации.

Полный процесс сжатия:
Исходные пиксели -> Предсказание строк фильтрации (выбор оптимальной фильтрации) -> Словарное сжатие LZ77 -> Кодирование Хаффмана -> Блок данных IDAT

Процесс распаковки полностью обратный:
Блок данных IDAT -> Декодирование Хаффмана -> Распаковка LZ77 -> Обратная фильтрация -> Исходные пиксели

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

4. Практическое сравнение: PNG vs JPEG vs WebP по размеру

Мы сравниваем эффект сжатия трёх форматов на одном и том же наборе тестовых изображений, охватывающих разные типы содержимого.

Тип изображенияРазмерИсходный BMPPNGJPEG(q80)WebP(q80)Степень сжатия PNG
Скриншот UI1920x10805.93MB0.35MB0.82MB0.28MB94.1%
Схема2000x15008.58MB0.42MB1.15MB0.35MB95.1%
Естественная фотография3000x200017.16MB12.50MB1.80MB1.42MB27.2%
Портретная фотография4000x300034.33MB28.80MB3.50MB2.80MB16.1%
Набор иконок1024x10243.00MB0.08MB0.45MB0.06MB97.3%
Сканированный документ2480x350824.80MB1.20MB0.85MB0.72MB95.2%

Практические данные раскрывают ключевой вывод: эффект сжатия PNG сильно зависит от типа изображения. Для скриншотов UI, схем, иконок с большими областями однотонного цвета степень сжатия PNG достигает 94%–97%, значительно превышая JPEG. Но для естественных фотографий, портретов с большой разницей между пикселями степень сжатия PNG составляет только 16%–27%, значительно уступая JPEG с 89%–90%.

Далее сравнение до и после оптимизации PNG, на примере стандартного PNG и оптимизированного PNG:

Тип изображенияСтандартный PNGОптимизированный PNGСнижение после оптимизацииСпособ оптимизации
Скриншот UI0.42MB0.35MB16.7%Фильтрация Paeth + максимальный уровень zlib
Схема0.52MB0.42MB19.2%Построчная оптимальная фильтрация + удаление метаданных
Набор иконок0.12MB0.08MB33.3%Преобразование в 8-битный индексированный цвет + оптимизация фильтрации
Сканированный документ1.50MB1.20MB20.0%Построчная оптимальная фильтрация + удаление gAMA

Оптимизация PNG в SmartSlim может уменьшить размер ещё на 15%–33% по сравнению со стандартным PNG, ключевой момент — комбинация построчного выбора оптимальной фильтрации и максимального уровня сжатия zlib.

Больше сравнений форматов можно найти в Сжатие без потерь vs сжатие с потерями: ключевые различия и Сравнение форматов WebP vs PNG vs JPG.

5. Часто задаваемые вопросы FAQ

Q1: Почему PNG — это сжатие без потерь?

PNG использует алгоритм DEFLATE для сжатия данных, который состоит из двух этапов: словарное сжатие LZ77 и кодирование Хаффмана. LZ77 ищет повторяющиеся последовательности байтов и заменяет их ссылками расстояние+длина, Хаффман использует коды переменной длины, позволяя часто встречающимся данным использовать короткие коды. Оба этапа обратимы — при распаковке декодирование Хаффмана восстанавливает коды переменной длины, LZ77 по ссылкам восстанавливает исходные байты, данные полностью идентичны без потери какой-либо информации, поэтому PNG — это сжатие без потерь.

Q2: У PNG или JPEG выше степень сжатия?

Для фотографий степень сжатия JPEG значительно выше, чем PNG. Фотография 3000x2000: PNG около 12.5MB, JPEG качество 80 около 1.8MB, разница в 7 раз. Потому что JPEG использует сжатие с потерями DCT, отбрасывая высокочастотные детали, а PNG должен без потерь сохранять каждый пиксель. Но для схем, скриншотов, иконок с большими областями однотонного цвета PNG наоборот меньше — скриншот UI: PNG 0.3MB, JPEG качество 80 около 0.8MB. Выбор формата зависит от типа содержимого.

Q3: Какова максимальная степень сжатия PNG?

Зависит от содержимого изображения. Изображения с большими областями однотонного цвета или градиентов могут иметь степень сжатия более 90% (например, скриншот UI с 5MB до 0.3MB); фотографии с большим количеством шума обычно имеют степень сжатия только 10%-30%, потому что большая разница между пикселями, LZ77 не может найти повторяющиеся последовательности. Теоретический предел PNG с алгоритмом DEFLATE примерно на уровне сжатия ZIP, невозможно получить такую высокую степень сжатия, как JPEG, путём отбрасывания информации.

Q4: В чём разница между оптимизацией PNG и сжатием PNG?

Сжатие PNG означает кодирование исходных данных пикселей с помощью DEFLATE в формат PNG, это стандартный процесс. Оптимизация PNG — это дальнейшее уменьшение размера на основе стандартного сжатия, включая: попытку 5 видов предсказания строк фильтрации и выбор оптимального, использование максимального уровня сжатия zlib, удаление метаданных chunk (например, tEXt/gAMA), преобразование 24-битного RGBA в 8-битный индексированный цвет (если цветов ≤256). Оптимизация PNG в SmartSlim может уменьшить размер ещё на 15%-30% по сравнению со стандартным PNG.

Заключение

PNG может обеспечить сжатие без потерь, ключевой момент в том, что оба этапа алгоритма DEFLATE, LZ77 и Хаффман, — это полностью обратимые математические операции, плюс предварительная обработка предсказанием строк фильтрации повышает сжимаемость данных. PNG показывает отличный эффект сжатия для скриншотов UI, схем, иконок с большими областями однотонного цвета (степень сжатия 94%–97%), но для фотографий степень сжатия ограничена (16%–27%), в этом сценарии следует выбрать JPEG или WebP.

Если вам нужно оптимизировать размер PNG-изображений, SmartSlim на основе движка сжатия Rust предоставляет построчную оптимальную фильтрацию и максимальный уровень сжатия zlib, уменьшая размер ещё на 15%–33% по сравнению со стандартным PNG, поддерживает 9 форматов изображений png/jpg/jpeg/webp/bmp/tiff, локальное сжатие без передачи данных.

Нужно сжать файлы? Попробуйте SmartSlim

Основан на собственном движке сжатия Rust, поддерживает 10 основных категорий и более 40 форматов, включая PDF/изображения/видео/Office/OFD, локальное сжатие без передачи данных.