PNG - це комбінація фільтрів + LZ77 + Хаффмана (комбінація LZ77 + Хаффмана називається «Дефляція») у такому порядку:
крок 1) якщо фільтр відрізняється від None, значення пікселів замінюється різницею від сусідніх пікселів (детальніше див. http://www.libpng.org/pub/png/book/chapter09.html ) . Це збільшує стиснення зображень градієнтами (так ... 4 5 6 7 стає ... 1 1 1 1), і це може допомогти в областях одного кольору (... 3 3 3 5 5 5 5 5 стає 0 0 0 2 0 0 0 0 0). За замовчуванням фільтри увімкнено в 24-бітових зображеннях та відключені у 8-бітових зображеннях з палітрою.
крок 2) дані стискаються з LZ77, який замінює повторні (збіги) рядки байтів з кортежем, що містить відстань до збігу та довжину збігу.
крок 3) результат кроку 2 кодується кодом Хаффмана, який замінює символи фіксованої довжини кодами змінної довжини, чим частіше символ тим коротший код.
Існує кілька питань:
Невелика зміна, яка впливає на кілька пікселів, призведе до зміни результатів за допомогою 3 кроків стиснення png:
1) Відфільтроване значення сусідніх пікселів буде змінюватися (залежно від використовуваного фільтра). Це посилить наслідки невеликих змін.
2) Зміна означатиме, що відповідність цій галузі буде різною. Наприклад, зміна 333333 на 333533 призводить до того, що інше явище 333333 більше не збігатиметься, тому воно вибере інший збіг до 333333 з іншою відстані або вибере той самий збіг, але з меншою довжиною, а потім інший збіг за останні 3 байти. Саме по собі це сильно змінить результати.
3) Найбільша проблема полягає в кроці 3. Код Хаффмана використовує змінну кількість бітів, тому навіть невелика зміна призведе до того, що все, що випливає, більше не вирівнюється. AFAIK Більшість алгоритмів стиснення не можуть виявити збіги, які не вирівняні в байтах, що запобіжить (або принаймні зменшить багато) стиснення вже стислих даних, що слідують за зміною, якщо компресор не може виявити збіги, які не вирівняні в байтах.
Інші питання вже охоплені іншими відповідями:
4) Gzip використовує той самий алгоритм Дефляції зі словником 32 КБ, тому, якщо файлів png більше 32 КБ, збіги не будуть виявлені, навіть якщо вони однакові. У цьому аспекті Bzip2 кращий, оскільки він використовує блок 900 КБ. XZ використовує LZMA, IIRC має словник 4 Мб у рівні стиснення за замовчуванням. 5) Формат Zip не використовує суцільне стиснення, тому він не буде краще стискати подібні або однакові файли.
Можливо, компресори з сімейства PAQ або PPMD будуть стискатись краще, але якщо вам потрібно стиснути безліч подібних файлів зображень, тоді ви можете розглянути 3 підходи:
1) Зберігайте зображення нестисненими (з PNG -0 або у форматі без стиснення) і стискайте компресором з великим розміром словника або блоку. (LZMA буде добре працювати)
2) Ще одним варіантом буде збереження фільтрів, але видалення стиснення Спуску з PNG. Це можна зробити, наприклад, за допомогою утиліти ( AdvDef ). Потім ви стискаєте отримані нестиснені PNG. Після декомпресії ви можете зберігати нестиснений PNG або стискати їх знову за допомогою AdvDef (але це займе час).
Вам потрібно перевірити обидва підходи, щоб побачити, що стискає найбільше.
3) Останнім варіантом буде перетворення png-зображень у відео, стиснення його за допомогою відеокомпресора без втрат на зразок x264 без втрат (особливо уважно використовуючи правильний кольоровий формат), а потім після вилучення витягніть кадри на окремі зображення PNG. Це можна зробити за допомогою ffmpeg. Вам також потрібно зберегти відображення між номером кадру та оригінальною назвою.
Це був би найскладніший підхід, але якщо PNG є частиною анімації, це може бути найефективнішим. Однак вам знадобиться формат відео, який підтримує прозорість, якщо він вам потрібен.
Редагувати: Існує також формат СПГ, якщо він використовується не часто.