Репост из: Mithgol the Webmaster
Незадолго до конца прошлого (2021) года я освоил одно средство сжатия файлов PNG, которое существует ещё с прошлого столѣтія, но которое недосуг было освоить прежде — pngquant.
История такова: с одной стороны, 1 октября 1996 года (болѣе четверти вѣка тому назад!), когда появился формат PNG, для Всемірной Паутины он стал первым таким форматом, который обеспечил возможность хранения полноцвѣтныхъ изображений (а не одних только 256-цвѣтныхъ, как GIF), притом подвергаемых сжатию информации без внесения потерь (а не съ непремѣннымъ внесением потерь, как JPEG; ну то есть были и попытки сдѣлать версию JPEG без внесения потерь, но широкой поддержки в WWW не получили).
С другой стороны, в течение первых же лѣтъ существования PNG стало понятно, что сжатие без потерь имѣетъ свой предѣлъ, так что полноцвѣтный файл PNG (до сжатия тратящий по 24 бита на пиксел) почти всегда будет существенно крупнѣе по объёму, чѣмъ малоцвѣтный (тратящий на каждый пиксел всего-навсего по 8 битов, а в случае небольших палитр — даже 4 или 2 бита, а для двуцвѣтныхъ изображений — и всего только по 1 биту на пиксел).
Слѣдовательно, если нѣкоторое изображение изрядно много вѣситъ въ полноцвѣтномъ PNG, но сжимать его в JPEG не хочется, то можно автоматически уменьшить число цвѣтовъ, чтобы достигнуть нѣкоторого сжатия с потерями, внесёнными таким путём — и pngquant как раз и рѣшаетъ задачу такого уменьшения, причём не тупо в лоб, а посредством разумного подбора цвѣтовъ для палитры (чтобы цвѣта исходного изображения не слишком отличались от конечных) и затѣмъ ещё разумного перераспредѣленія вносимых потерь (совершаемого по алгоритму Флойда и Штейнберга, но только для пикселов с достаточным количеством сосѣдей того же конечнаго цвѣта).
Бывают двѣ причины предпочесть такое «квантование» JPEGованию:
⓵ Если изображение содержит прозрачные и (или) полупрозрачные области, то тогда в формате JPEG (в котором всѣ пикселы непрозрачны) для них придётся выбрать фоновый цвѣтъ. Уменьшение цвѣтности, привносимое pngquant, оказывается тогда предпочтительнѣе по сравнению с искажением цвѣтности в случае несоѿвѣтствія реальнаго фона и предполагавшагося. Напримѣръ, растровыя копіи сообщений, взятых из Телеграма, окружены прозрачными полями (с кружком аватара) вон в той моей микроблогозаписи в Твиттере (совмѣстно — на бѣломъ фонѣ, но Twitter подмѣняетъ фонъ на цвѣтной при разглядывании изображений по одному).
⓶ Если число используемых цвѣтовъ «недалеко ушло» от восьмибитных изображений (то есть цвѣтовъ больше 256, но всё же не миллионы их, и не сотни тыщщ, и даже не десятки тыщщ), как это случается, напримѣръ, на скриншоте с текстами двухъ цвѣтовъ и значкомъ третьяго цвѣта, то тогда итог pngquant (почти незамѣтный сдвиг от одного цвѣта к другому сосѣднему) предпочтительнѣе по сравнению с шумом DCT, привносимым JPEG (который проявляется как «расходящиеся волны» вокруг любых рѣзкихъ линий, и как «вьющаяся мошкара» вокруг мелких деталей, и «размытие по квадратику» у острых углов и у диагоналей), при примѣрно равном объёме файла.
Чего ж я тогда ≈20 лѣтъ пренебрегал этим средством? — а вот чего:
① И фото, и нетекстовые скриншоты (или такие, на которых мало текста, но много фотографий или фотореалистической компьютерной графики), и даже мои сшивки кадров аниме — всѣ, всѣ настолько полноцвѣтны, что их замѣтно портит любое сильное уменьшение количества цвѣтовъ, будь то постеризация или алгоритм Флойда и Штейнберга.
② Если можно скинуть файл JPEG с качеством, близким к максимальному (а тот же Twitter принимает до 5 мегабайтов при соблюдении ряда правил), или если помѣщается файл PNG без потерь (сжатый современными средствами по алгоритму Zopfli — напримѣръ, в oxipng), то тогда при нынешних скоростях Интернета экономить объём внесением потерь не так важно, как в эпоху дайалапа и GPRS.
③ Пришли новые способы хранения изображений (формат WebP с 2010 и 2011 года, а в недавние годы — форматы AVIF и JPEG XL), достигающие лучшаго соѿношенія качества и объёма файла без нужды в прежних приёмах внесения потерь, но располагающие собственными, менѣе замѣтными (наподобие near_lossless в WebP).
История такова: с одной стороны, 1 октября 1996 года (болѣе четверти вѣка тому назад!), когда появился формат PNG, для Всемірной Паутины он стал первым таким форматом, который обеспечил возможность хранения полноцвѣтныхъ изображений (а не одних только 256-цвѣтныхъ, как GIF), притом подвергаемых сжатию информации без внесения потерь (а не съ непремѣннымъ внесением потерь, как JPEG; ну то есть были и попытки сдѣлать версию JPEG без внесения потерь, но широкой поддержки в WWW не получили).
С другой стороны, в течение первых же лѣтъ существования PNG стало понятно, что сжатие без потерь имѣетъ свой предѣлъ, так что полноцвѣтный файл PNG (до сжатия тратящий по 24 бита на пиксел) почти всегда будет существенно крупнѣе по объёму, чѣмъ малоцвѣтный (тратящий на каждый пиксел всего-навсего по 8 битов, а в случае небольших палитр — даже 4 или 2 бита, а для двуцвѣтныхъ изображений — и всего только по 1 биту на пиксел).
Слѣдовательно, если нѣкоторое изображение изрядно много вѣситъ въ полноцвѣтномъ PNG, но сжимать его в JPEG не хочется, то можно автоматически уменьшить число цвѣтовъ, чтобы достигнуть нѣкоторого сжатия с потерями, внесёнными таким путём — и pngquant как раз и рѣшаетъ задачу такого уменьшения, причём не тупо в лоб, а посредством разумного подбора цвѣтовъ для палитры (чтобы цвѣта исходного изображения не слишком отличались от конечных) и затѣмъ ещё разумного перераспредѣленія вносимых потерь (совершаемого по алгоритму Флойда и Штейнберга, но только для пикселов с достаточным количеством сосѣдей того же конечнаго цвѣта).
Бывают двѣ причины предпочесть такое «квантование» JPEGованию:
⓵ Если изображение содержит прозрачные и (или) полупрозрачные области, то тогда в формате JPEG (в котором всѣ пикселы непрозрачны) для них придётся выбрать фоновый цвѣтъ. Уменьшение цвѣтности, привносимое pngquant, оказывается тогда предпочтительнѣе по сравнению с искажением цвѣтности в случае несоѿвѣтствія реальнаго фона и предполагавшагося. Напримѣръ, растровыя копіи сообщений, взятых из Телеграма, окружены прозрачными полями (с кружком аватара) вон в той моей микроблогозаписи в Твиттере (совмѣстно — на бѣломъ фонѣ, но Twitter подмѣняетъ фонъ на цвѣтной при разглядывании изображений по одному).
⓶ Если число используемых цвѣтовъ «недалеко ушло» от восьмибитных изображений (то есть цвѣтовъ больше 256, но всё же не миллионы их, и не сотни тыщщ, и даже не десятки тыщщ), как это случается, напримѣръ, на скриншоте с текстами двухъ цвѣтовъ и значкомъ третьяго цвѣта, то тогда итог pngquant (почти незамѣтный сдвиг от одного цвѣта к другому сосѣднему) предпочтительнѣе по сравнению с шумом DCT, привносимым JPEG (который проявляется как «расходящиеся волны» вокруг любых рѣзкихъ линий, и как «вьющаяся мошкара» вокруг мелких деталей, и «размытие по квадратику» у острых углов и у диагоналей), при примѣрно равном объёме файла.
Чего ж я тогда ≈20 лѣтъ пренебрегал этим средством? — а вот чего:
① И фото, и нетекстовые скриншоты (или такие, на которых мало текста, но много фотографий или фотореалистической компьютерной графики), и даже мои сшивки кадров аниме — всѣ, всѣ настолько полноцвѣтны, что их замѣтно портит любое сильное уменьшение количества цвѣтовъ, будь то постеризация или алгоритм Флойда и Штейнберга.
② Если можно скинуть файл JPEG с качеством, близким к максимальному (а тот же Twitter принимает до 5 мегабайтов при соблюдении ряда правил), или если помѣщается файл PNG без потерь (сжатый современными средствами по алгоритму Zopfli — напримѣръ, в oxipng), то тогда при нынешних скоростях Интернета экономить объём внесением потерь не так важно, как в эпоху дайалапа и GPRS.
③ Пришли новые способы хранения изображений (формат WebP с 2010 и 2011 года, а в недавние годы — форматы AVIF и JPEG XL), достигающие лучшаго соѿношенія качества и объёма файла без нужды в прежних приёмах внесения потерь, но располагающие собственными, менѣе замѣтными (наподобие near_lossless в WebP).