Основною мотивацією для формату PNG було створення заміни GIF, яка була не тільки безкоштовною, але й покращенням по суті в усіх відношеннях. В результаті стиснення PNG повністю втрачається - тобто оригінальні дані зображення можна реконструювати точно, побіжно - так само, як у GIF та більшості форм TIFF.
PNG використовує двоступеневий процес стиснення:
- Попереднє стиснення: фільтрування (прогнозування)
- Стиснення: DEFLATE (див. Wikipedia )
Крок попереднього стиснення називається фільтруванням, що є методом оборотного перетворення даних зображення, щоб основний двигун стиснення міг працювати ефективніше.
Як простий приклад, розглянемо послідовність байтів, що рівномірно збільшується від 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 (немає дефляції) та 9 (максимальний дефлятор). Як зазначені рівні 0-9 впливають на використання фільтрів, які є основною особливістю оптимізації PNG, все ще залежить від розробника інструменту.
Висновок полягає в тому, що PNG має параметр стиснення, який може значно зменшити розмір файлу, без втрати навіть одного пікселя.
Джерела:
Документація по libpng для портативної мережевої графіки Вікіпедії
Розділ 9 - Стиснення та фільтрація