Оптимизация PNG и JPEG без потери качества. Часть 1

:

Введение


Предлагаю Вашему вниманию обзор посвященный оптимизации изображений формата PNG и JPEG без потери качества. Под «без потери качества» подразумевается, что визуально оригинальные и оптимизированные изображения ни чем не будут отличаться. Я читал на Хабре довольно много статьей посвященных данному вопросу, но скажу, большая часть — полная чушь, в них констатируются факты, а не причины. Данный обзор посвящен людям, которые имеют базовые знания об оптимизации изображений.

PNG


И так, как же происходит оптимизация? Давайте разберемся по порядку, в основном это происходит из-за нескольких причин, и сейчас мы их рассмотрим.
Non-interlaced или Interlaced

Существуют два метода отображения изображений в браузере при загрузке:
  • Non-interlaced — браузеры загружают их последовательно, сверху вниз, по мере поступления информации из сети.
  • Interlaced — до полной загрузки файла изображение в браузере отображается в низком разрешении. т.е. сначала Вы увидите изображение низкого качества, затем, по мере поступления графической информации, качество изображения будет постепенно улучшаться. Чересстрочное отображение позволяет уменьшить субъективное время загрузки и показать пользователям, что изображение загружается, однако чересстрочное отображение также увеличивает размер файла.
В заключении дам пару ссылок, где подробнее рассмотрены способы отображения изображений в браузере при загрузке.
ColorType и BitDepth

ColorType нужен для оптимизации количества цветов в изображении. По этому критерию бываю следующие форматы PNG:
  1. Grayscale;
  2. Grayscale + alpha;
  3. Palette (256 цветов);
  4. RGB;
  5. RGB + alpha.
Технология ColorType как раз выбирает тот формат, при котором изображение будет весить меньше всего, но при этом визуально не изменится. Вот пример работы данной технологии (чтобы было честно, изображения были оптимизированы по одному и тому же алгоритму):

PNG RGB + alpha — 17 853 байт

image

PNG Palette — 13 446 байт

image

Разница в размере — 4407 байт (24%), при этом визуально картинки не изменились. Если Вы видите разные изображение, то это оптический обман.

BitDepth — битовая глубина, бывает двух видов:

  1. 1-bit;
  2. 2-bit;
  3. 4-bit;
  4. 8-bit;
  5. 16-bit.
Технология BitDepth аналогично ColorType.
Вот пример работы данной технологии (чтобы было честно, изображения были оптимизированы по одному и тому же алгоритму):

PNG 4-bit — 6 253 байт

image

PNG 8-bit — 5 921 байт

image

Разница в размере — 332 байт (5,3%), при этом визуально картинки не изменились. Если Вы видите разные изображение, то это оптический обман.

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

Chunks

Если кто в танке не в курсе, PNG состоит из Chunks. Писать, что это такое Chunks не буду, можете сами прочитать. Лучше я покажу, для этого есть программа — TweakPNG, возьмите любое изображение формата PNG и откройте через данную программу и увидите всю структуру PNG.

image

Есть еще программы наподобие TweakPNG, но она лучшая и удобная. Об остальных программах расскажу в заключении.

Как видно из выше приведенного рисунка, существуют два вида Chunk (столбец Attributes):

  • Critical chunks присутствуют в любом PNG-изображении (IHDR, PLTE для PNG Palette, один и более IDAT и IEND).
  • Ancillary chunks являются дополнительными chunks, удаление тех или иных chunks позволяет уменьшить размер изображения, но не намного.
Оптимизация палитры

Может быть реализована только в PNG Palette, технология основана на оптимизации chunks PLTE, может уменьшить размер изображения, хотя и не намного. На мой взгляд лучше все это технология реализована в Color Quantizer, один из его алгоритмов был реализован и в TruePNG.
Оптимизация альфа-канала

Про эту технологию узнал от Сергея Чикуенока ( Про PNG. Часть 3). Сейчас эта технология развита, и используется очень часть и дает существенный прирост к оптимизации. Главный недостаток — технология вводит изменения в само изображение (в Chunks IDAT), а не в структуру, однако визуально изображение не изменится. Могу привести в пример две программы:
  • TruePNG от автора Color Quantizer;
  • CryoPNG — более продвинутая технология оптимизации и требует большего времени, может увеличить степень сжатия.
Понимаю, тяжело понять, о чем я пишу, лучше покажу пример (чтобы было честно, изображения были оптимизированы по одному и тому же алгоритму, первое изображение с альфа-каналом, другое без альфа-канала).

Оригинальное изображение. Размер — 214 903 байт.

image
image

CryoPNG (параметр -f0). Размер — 107 806 байт.

image
image

CryoPNG (параметр -f1). Размер — 105 625 байт.

image
image

CryoPNG (параметр -f2). Размер — 107 743 байт.

image
image

CryoPNG (параметр -f3). Размер — 114 604 байт.

image
image

CryoPNG (параметр -f4). Размер — 109 053 байт.

image
image

Недостаток CryoPNG — требуется оптимизация всех пяти изображений для выявления наилучшего результата, а это в свою очередь требует большого количества времени.
TruePNG работает в этом плане аналогично CryoPNG -f0, в свою очередь CryoPNG -f0 является оптимальным с точки зрения оптимизации PNG (как говорится это просто опыт). По моим наблюдениям, CryoPNG -f1 и CryoPNG -f4 намного чаще оптимизируют PNG лучше CryoPNG -f0, по сравению с CryoPNG -f2 и CryoPNG -f3.

Алгоритм сжатия Deflate + Фильтрация строк

Как мы же говорили, PNG состоит из Chunks, в данном случае, нас интересует Chunks — IDAT. Для его сжатия в основном играют два фактора, фильтрация строк и алгоритм сжатия Deflate. Давайте об этом поговорим поподробнее.
Фильтрация строк

Фильтры, которые применяются в PNG, нужны для того, чтобы подготовить данные к сжатию и таким образом увеличить его степень. Фильтр обрабатывает каждую строку таким образом, чтобы приходилось кодировать не сами значения байтов, а разницу между текущим и предыдущим. От фильтра зависит, какой считается предыдущим.
  1. None — фильтр отсутствует;
  2. Sub смотрит байт в той же строке;
  3. Up — с тем же номером, что и текущий в предыдущей;
  4. Average берет оба и считает от них среднее арифметическое;
  5. Paeth смотрит байт перед байтом в предыдущей строке, сравнивает разницу и кодирует наименьшую.
Вообще говоря, нет каких-то определенных рекомендаций, какой фильтр выбирать. Для каждой строки можно выбрать свой фильтр, поэтому часто просто применяют все фильтры подряд и смотрят, с каким сжатие получается лучше всего. Существует еще один фильтр — Adaptive, — можно сказать это «микс» из фильтров. Фильтры поддерживают почти все программы оптимизаторы PNG, но лично мне известны только две программы, которые имеют более продвинутую систему создания фильтров:
PNGOut не создает такие фильтры, однако в новой версии появилась поддержка встроенных фильтров. Это было сделано по моей просьбе.
Алгоритм сжатия Deflate

На сегодняшний день есть несколько библиотек, основанных на алгоритме сжатия Deflate:
Библиотека
Deflate
Скорость
работы
Степень
сжатия
Программы Примечание
Zlib Высокая Низкая TruePNG
OptiPNG
PNGWolf
Благодаря высокой скорости работы может быстро перебрать большое количество значение параметров и выбрать оптимальные.
7-zip Средняя Средняя AdfDef
PNGWolf
Не всегда выбранные значения параметров в Zlib являются для них оптимальными (близки к оптимальным). Перебор значений параметров будет занимать большое количество времени и почти всегда затраченное время не оправдывает полученный результат.
Kzip Низкая Высокая PNGOut
PNGWolf использет одновременно и Zlib, и 7-zip.

Важно: все эти программы дополняют друг друга, и они сильны, когда едины. Это самое большая проблема, когда их используют отдельно, а потом сравнивают полученные результаты. В первую очередь надо использовать Zlib, а потом уже 7-zip и/или Kzip.

В следующей части мы поговорим об этих программах поподробнее, а также построим три алгоритма оптимизации PNG (с учетом оптимизации альфа-канала) по степени сжатия и затраченного времени. Ниже приведен условный график зависимости степени сжатия от затраченного времени на оптимизацию Chunks IDAT.

image

Как видно из графика, чем больше степень сжатия, тем больше времени требуется.

И еще немного...


Здесь мы поговорим о двух программах:
Рекомендую их использовать в самом конце оптимизации PNG и в том порядке, котором написал выше. Могут уменьшить размер PNG на несколько десятков байт, при этом скорость работы очень высокая.

JPEG


Итак мы переходим к JPEG, здесь все гораздо проще, и так продолжим. Но перед этим скажу, что JPEG нельзя пересохранить не потеряв качество, даже со степенью качеством 100 (это не максимальное качество, а математический предел оптимизации). Рассмотрим следующий пример (чтобы было честно, изображения были оптимизированы по одному и тому же алгоритму).

Оригинальное изображение — 52 917 байт.

image

Новое изображение (сохранен через Adobe Photoshop CS5, Save for Web 100) — 53 767 байт

image

Строим diff-разницу изображений.

image

Вот так вот сильно изменилась картинки, да, визуально ничего не заметно. Как видно размер картинки увеличился. Это из-за специфики библиотеки, которая создает JPEG, о библиотеках поговорим чуть позже.

Есть только одна программа, которая позволяет пересохранить изображения в JPEG не потеряв качество — BetterJPEG (есть плагин к Adobe Photoshop). Если не ошибаюсь, для жителей стран СНГ для некоммерческого использования программа бесплатная. Лично я использую BetterJPEG, когда нет исходника и требуется незначительное редактирование изображения. Рассмотрим пример работы BetterJPEG.

Оригинальное изображение.
image
Новое изображение (усложняем ситуацию, добавляем надпись «HTML»).
image
Строим diff-разницу изображений.

image

Markers

JPEG в отличие от PNG состоит из маркеров. Рекомендую прочитать статью «Структура файла, маркеры», также рекомендую вообще посмотреть сам сайт. Самая мощная программа по изучению структуры JPEG — JPEGsnoop. Есть еще программы, но о них расскажу в заключении. Для изучения структуры JPEG рекомендую следующее изображение — PhotoME.
Удаления некоторых маркеров (APP0-APP15, COM), может существенно уменьшить размер изображения. Мне больше всего для этого нравится программа — Jhead, наиболее простая и удобная.
Progressive и Optimized

Существуют три метода отображения изображений в браузере при загрузке.
  • Стандартный. Сейчас почти не используется, аналогичен оптимизированному методу (степень сжатия хуже).
  • Оптимизированный (Optimized) — создается улучшенный файл JPEG с меньшим размером файла. Браузеры загружают их последовательно, сверху вниз, по мере поступления информации из сети.
  • Прогрессивный (Progressive) — изображение выводится как последовательность наложений, что позволяет отобразить изображение с низким разрешением до полной его загрузки, т.е. сначала Вы увидите изображение низкого качества, затем, по мере поступления графической информации, качество изображения будет постепенно улучшаться. Internet Explorer, включая восьмую версию, не поддерживает прогрессивную загрузку JPEG, он его показывает только после полной загрузки файла, что сильно отличается от поведения «традиционного» JPEG, когда изображение отображается сверху вниз, по мере загрузки.
Подробнее об этом можно прочитать в статье «Оптимизация изображений, часть 4: последовательные JPEG — быть или не быть?»
Библиотека создания JPEG

А вот здесь начинается самое интересное. Никто не задумывался, как создается JPEG? Оказывается, существуют библиотеки, и их не так и много, рассмотрим некоторые из них:
  • Adobe использует свои собственные библиотеки, их вообще несколько, например, Adobe Photoshop, Save for web — используется для сохранения в WEB.
  • LibJPEG. Использую почти все программы, которые умеют сохранять в JPEG, включая Adobe Fireworks. В библиотеке LibJPEG есть очень интересная программа — JPEGTran (оптимизирует изображение, без потери качества). Имеет смысл применять, если Вы создаете изображения JPEG через Photoshop или Illustrator и оптимизируете через JPEGTran, то получаете максимальный эффект оптимизации, т.к. выходит, что используются две библиотеки. К сожалению, у меня так и не получилось заставить Photoshop сохранять в JPEG, без потери качества.
Помните, когда мы пересохраняли изображение в JPEG, вышло, что новое изображение больше оригинала. Это связано из-за специфики библиотек. Вот небольшой обзор работы библиотек — Corel Painter vs Adobe Photoshop.

Сказать какая из двух библиотек оптимизирует лучше, вопрос очень сложный и не однозначный, но из-за очень высокой скорости работы JPEGTran, Вы просто не замечаете его работу, только не забывайте проверять размер изображения, увеличился или нет, Все это можно сделать и через bat. Помните, JPEGTran может переводить JPEG из Progressive в Optimized и наоборот, не изменяя саму картинку.

Заключение


Это конечно все причины, но наиболее существенные. Почти со всеми авторами приведенных программа я общался, и все они очень талантливые люди. Хотел отдельно поблагодарить x128 за огромную помощь в изучении оптимизации изображений.

Подробнее о способах отображения изображений в браузере при загрузке можно прочитать:

Чтобы убедиться, что вышеописанные способы действительно оптимизируют без потери качества, предлагаю посмотреть способ построения diff-разницы изображений.
Для более полного представлении об оптимизации, рекомендую прочитать следующие статьи:
  1. Работа с изображениями
  2. Подготовка изображений к загрузке
  3. Оптимизация GIF и PNG-8 для веб
Дополнительно программное обеспечение, которое рекомендую использовать, при изучении структуры изображений и не только:
  1. PhotoME — очень удобная программа для изучения структуры PNG и JPEG, не такая мощная, как описанные выше, использую как основную.
  2. ExifTool — очень мощная программа для изучения структуры PNG и JPEG. Работает через командную строку, есть онлайн версия — Jeffrey's Exif Viewer
  3. 010 Editor — Hex-редактор, но имеет дополнение (JPEG, PNG + Chunks), которое помогает изучению структуры PNG и JPEG, иногда просто не заменим.
В заключении, бы хотел поговорить об онлайн-сервисе оптимизации изображений — PunyPng. Не могу сказать, что он совершенен с точки зрения оптимизации, но на сегодняшний день он лучший из тех, которых я встречал.