• ФДВР. Каналы и маски: практика — II

    Продолжаем мучить фотошоп в поисках оптимального способа сохранения графики в формате PNG. Сегодня мы рассмотрим способ оптимизации, основанный на восприятии цвета человеческим глазом (йес! давно хотелось написать что-нибудь такое пафосное :). Выражаясь человеческим языком: мы будем снижать детализацию полупрозрачных областей картинки.  Именно тех областей, на которые обычный зритель не обращает внимания.

    Прежде чем приступать к оптимизации, необходимо разобраться, как сохраняются полупрозрачные PNG (PNG24 в терминологии фотошопа). В этом формате каждый пиксель описывается четырьмя байтами: RGBA (red, green, blue, alpha). Последний байт отвечает за прозрачность.

    Возьмем для примера два пикселя в формате RGBA: 123,49,54,0 и 65,130,60,0. Несмотря на то, что значения этих пикселей разные, для зрителя они выглядят абсолютно одинаково: они оба полностью прозрачные. Так как пиксели разные, PNG-упаковщик не сможет их нормально обработать фильтрами. А что будет, если мы оба этих пикселя заменим на 0,0,0,0 и 0,0,0,0? Зритель совершенно ничего не заметит, а вот для упаковщика разница будет огромной: эта последовательность гораздо эффективнее упаковывается фильтрами. Приведенный выше пример можно записать как 0(8), то есть значение 0 повторить 8 раз.

    Именно на этом и будет основан наш способ оптимизации — мы будем заменять детализированные полупрозрачные области на менее детализированные, которые будут лучше упаковываться. Для этого урока нам понадобится плагин Remove Transparency.

    Откроем исходное изображение в фотошопе:

    stage13

    Оригинал весит 199 КБ. Первое, что бросается в глаза, это тень часов и блики маятника. Продублируем текущий слой и выполним на нем фильтр Photo Wiz → Remove Transparency. Теперь мы видим, что же на самом деле сохранилось в изображении:

    stage22

    Посмотрим поближе на тень:

    stage32

    Отчетливо виден шум, но сама область — полупрозрачная (прозрачность менее 50%), и пользователь его совсем не заметит.

    Эта область — наш основной кандидат на оптимизацию. Если бы у нас был исходник, мы бы просто переделали тень, перезалив ее сплошным цветом (вы можете увидеть это в скринкасте). Но что делать, если исходник нам не доступен? Правильно — нам помогут волшебные маски. Наша задача: «упростить» цвета в полупрозрачных областях. Для этого нам пригодится фильтр Median, который сглаживает переходы между пикселями.

    Делаем Ctrl+клик или ⌘+клик по слою Layer 0 и создаем на основе выделения маску для слоя Layer 0 copy (если вы не знаете, как это сделать, перечитайте предыдущие уроки). Переходим в палитру Channels и делаем дубликат канала с маской. Теперь необходимо указать область воздействия фильтра Median. Сами часы трогать нельзя, а вот с тенью и бликами можно немного поиграться. Инвертируем маску (Ctrl+I или ⌘+I) и применяем к ней Levels (Ctrl+L или ⌘+L). Передвигаем светлый ползунок влево до значения 75 (подбирается на глаз). Таким образом мы получили маску, которой будет ограничиваться действие фильтра Median:

    stage42

    Выделяем текущий канал (Ctrl+клик или ⌘+клик), переходим в палитру Layers, кликаем на пиктограмме изображения в слое Layer 0 copy (именно на нее, а не на маску) и применяем фильтр Noise → Median. Значение радиуса выбираем на глаз, у меня получилось 3:

    stage51

    Как видите, шум совсем пропал. Попробуем сохранить изображение в формате PNG (не забудьте включить маску, если вы ее отключили).

    result1

    У меня получилось изображение весом 172 КБ (было 199 КБ) — вполне неплохо за такое короткое время. А умные мальчики и девочки должны сразу догадаться, что можно еще оптимизировать саму маску (например, с помощью Posterize или цветового режима Indexed) и сделать вес картинки еще меньше :).

    Я показал простой способ оптимизации полупрозрачные области изображения. Но наибольший эффект достигается при комбинировании этого способа со способом из предыдущего урока. Алгоритм такой: сначала оптимизируете «сердцевину» — непрозрачные пиксели, — перегнав их в индексирванную палитру, затем добавляете полупрозрачные пиксели, снизив им детализацию. Тогда у вас получится такой же результат, как в этом примере: со 199 КБ сможете ужать картинку до 88 КБ без видимых ухудшений.

    ***

    Так получилось, что я пока не знаю, что можно еще написать на тему использования фотошопа для веб-разработки. Можете в комментариях предлагать свои идеи и задавать вопросы, самые интересные и востребованные будут описаны в виде уроков. Это могут быть как общие вопросы (например, как оптимизировать JPEG), так и частные (есть макет, как лучше всего сохранить графику).

  • 11 комментариев

    1. 28 апреля 2009

      Спасибо за статью, Сергей.
      Ждем продолжения =)

    2. 28 апреля 2009

      > Так получилось, что я пока не знаю, что можно еще написать на тему использования фотошопа

      Может чего-нибудь про оптимизацию js написать? 🙂

    3. Сергей Чикуенок
      28 апреля 2009

      Можно и про JS. Напишу.

    4. 29 апреля 2009

      Посещаемость сайта растёт?

    5. Сергей
      30 апреля 2009

      Спасибо, интересная статья.
      Если можно, то напишите про оптимизацию jpeg пожалуйста.

    6. Сергей Чикуенок
      30 апреля 2009

      Про JPEG я уже писал.

    7. Сергей
      30 апреля 2009

      Спасибо, обязательно почитаю!

    8. Сергей
      4 мая 2009

      Хотелось бы узнать, в каких случаях целесообразно использовать спрайты и как оптимизировать изображения в таком случае и как их лучше сохранять? (на каком нибудь простом и не очень примере)

    9. 1 августа 2009

      И еще хотелось бы узнать про GIF. Больно мне этот формат нравится. Экономный, но со множеством непонятных аспектов, например сглаживание углов у фотографии. Получается как то не так, видно гребенку.

    10. Сергей Чикуенок
      2 августа 2009

      GIF уже давно устарел, пора использовать PNG

    11. Дмитрий
      14 августа 2010

      http://x128.ho.ua/color-quantizer.html — вот этой программой получилось уменьшить исходник до 80кб.
      Рузультат тут http://img1.openfile.ru/1018939/fv/10189391008140214185185.png