Сказ о старинных иконках. Загадка 18-и цветов. Прозрачный и инверсный цвета

DesignWrites
Sep 6, 2018 · 4 min read

Мало кому ныне не плевать на лишние килобайт-другой. Но такие люди есть, и как раз для такого задрота человека эта заметка и написана. )

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

Что это даёт? Иконка 48х48, 1-битовая прозрачность, 256 цветов = 3774 байта, она же в 16 цветах = 1662 байт. Выигрыш — 2 килобайта, при незначительном падении качества изображения.

Пример. Слева — направо:
• 256-цветный оригинал
• фиксированная стандартная 16-цветная палитра (причем здесь пару минут подбирал штриховку, чтоб изображение имело хоть сколько-нибудь приличный вид)
• адаптивная 16-цветная палитра + штриховка (dithering).

Как это работает? Как ни странно, 16-цветная иконка всегда носит в себе палитру. То есть, 99.9% старинных иконок несут в себе абсолютно одинаковую 64-байтную таблицу цветов (4 байта на цвет). И, да — оказывается, её можно перепрограммировать.

К сожалению, я не знаком с программой, что умеет полноценно работать с такого рода иконками. Поэтому вот рецепт, как «неполноценно» состряпать подобную иконку: возьмите IrfanView, загрузите в него картинку: либо заранее подготовленную 16-цветную, либо уменьшите количество цветов прямо в нём: меню — изображение — уменьшить глубину цвета… — 16 цветов. Теперь: меню — сохранить как… — выбрать формат .ico. Всё? Нет, не всё: Irfan View не умеет работать с прозрачностью, её придется восстановить вручную в другой программе. Microangelo Studio умеет загружать и редактировать такие иконки (увы, создавать из них библиотеку, ровно как и создавать такие иконки «с нуля» он не позволяет). Загружаем иконку в Microangelo и… возможно, с ходу получаем окошко с предупреждением насчет «некорректной палитры» — что это значит на практике, будет рассказано позже. Инструментами «заливка» и «карандаш» отмечаем прозрачные зоны; записываем; готово!

Это было то, что я делал раньше, лет десять назад. Теперь, внимательно присмотревшись к палитре Microangelo, у меня возникли вопросы. Что это за странная палитра, 18 цветов? Как вообще можно хранить 18 цветов в файле? Число-то не круглое, господа программисты так не поступают; им это просто не удобно. )) Видно, что в палитре есть сплошных 16 цветов и два служебных: «прозрачный» и «инверсный». Что за «инверсный»? — если такой цвет встречается, он отображает негатив того, что лежит под ним; используется это чаще всего в курсорах; а курсор — он и по сути и по структуре файла — тоже иконка. Но как хранятся все эти цвета? Если обычные точки изображения упакованы по 4 бита (16 цветов), то прозрачность может храниться только как отдельная битовая маска (1 бит на каждую точку изображения). Окей, а где же тогда хранится инверсия? Ещё одна маска, что ли? Не экономично, но возможно… Давайте-ка посчитаем.

Иконка 48х48, 16 цветов, 1 изображение. Размер файла 1662 байта. Что в нём? Я слабо представляю себе тонкости, но попробуем прикинуть. Главная часть, само изображение: 48*48/2 = 1152 байта. Палитра: 16*4 = 64 байта. Маска прозрачности 48*48/8 = 288 байт. Заголовок .ico, официально = 6 байт. Описание кадра (1 шт.) из документации = 16 байт. Итого: 1152+64+288+6+16 = 1526. Наверное, там есть что-то ещё, ведь реальный размер файла больше — но это не важно; важно другое, остаток «несходняка» мал: 136 байт, и он явно не позволяет разместить еще одну битовую маску размером 288 байт. Значит… инверсный цвет каким-то образом встроен в саму картинку. Может, теперь вы уж догадаетесь сами, как они это сделали?

А сделали они это, судя по всему, так: в оригинальных Windows (кажется, начиная с Win 95OSR2 полноценно, а в Win XP и более новых — уже частично), в иконках и курсорах, говоря строго — настоящего прозрачного цвета не существовало. Если альфа-маска показывала: текущая точка курсора/иконки «прозрачна» — брался цвет под курсором/иконкой и XOR-ился («исключающее “или”»; а может там было и просто вычитание) — внимание! — с текущим цветом точки, взятым из палитры иконки.

Что получается? Если это был первый цвет (черный в фиксированной палитре), XOR делал с фоном «ничего» — цвет становился просто прозрачным. Если это был последний цвет (в фиксированной палитре — белый) — цвет менялся полностью, превращался в негатив. Это и есть весь секрет, как хранились «18 цветов»… Т.е., еще раз: «прозрачный» = черный (+) альфа-маска, «инверсный» = белый (+) альфа-маска. А теперь — поговорим о «глюках».

Упомянутое выше предупреждение Microangelo гласит: «у вас в палитре нет полноценного белого и черного цветов, работа с прозрачностью будет некорректной!». И вправду, наша адаптивная палитра вполне может обойтись без черного или белого цветов. Как же тогда отработает прозрачность? О, именно так, как мы и ожидаем: возьмется какой-то цвет из палитры (например, зеленый), «отксорится» (XOR) с фоном, и мы получим прекрасный фиолетовый цвет вместо прозрачности. )) Или иной пример — на место последнего цвета в палитре случайно попал черный: и «инверсия» превратилась в обычную полноценную прозрачность.

Пример: слева стандартная палитра, справа перепрограммированная. Слева прозрачность (P) и инверсия (I) отрабатывают как надо; справа — явно нет.

Впрочем, все эти прелести иконок мы можем наблюдать только в оригинальных Windows. Современные ОС, такие как Win 10, игнорируют цвета палитры, и битовая маска «прозрачность» всегда работает именно как прозрачность в чистом виде: XOR-а нет, и инверсии соответственно нет тоже. Однако, в механизме отображения курсора, всё-таки есть совместимость — там работает полноценная старая добрая экономичная схема; «тёплая, ламповая», и… мало кому понятная и нужная.

Пример: различное отображение одних и тех же иконок в Windows XP и в Windows 7.

    DesignWrites

    Written by

    Наш Телеграмм канал: https://t.me/designwrite

    Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
    Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
    Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade