XPM: растровое изображение своими руками
Возьмём какую-нибудь тему из школьной информатики. Например, изучение растровой графики.
О чём по этой теме стоит разговаривать?
- О матричном представлении изображения, в том числе — о том, что одной только матрицы недостаточно: размеры, способ кодирования цвета, другая дополнительная информация
- О кодировании цветов и цветовых пространствах (как минимум — RGB, CMYK и HLS/HLV)
- Об упаковке изображения и об упаковке «с потерями»
- О проблемах геометрических преобразований
Ставить точки руками или обрабатывать области магией?
Среди этих тем некоторые — явно выше того, что можно в школе объяснить до конца (та же упаковка с потерями, например). Некоторые темы можно осветить только поверхностно. Можно запустить любой приличный редактор растровой графики и показать диалог выбора цвета в различных цветовых пространствах — какой при изменении параметров получается в результате цвет. Однако объяснять, почему цветовые пространства именно такие, придётся всё равно «на пальцах» (колбочки, палочки, складывание цветов, вычитание, а на освещённости/светлоте начинается уже математика).
Диалог выбора цвета в редакторе GIMP. Довольно поучительно начать изменять один параметр из пространства HSV и пронаблюдать, как движется «прицел» и вращается маркер цвета.
Геометрические преобразования стоит исследовать уже после близкого знакомства с предыдущими темами.
А вот теме «матричное представление изображения», как это ни странно, не хватает программной наглядности. С одной стороны, имеется растровый редактор, в котором всё вполне наглядно, своими руками делается. А с другой стороны, со стороны программиста — разнообразные прекрасные библиотеки для работы с разнообразными прекрасными растровыми форматами.
И вот эта пропасть слабо преодолима. Потому что библиотеки, в конечном счёте, описывают совсем не то, что человек делает в простейшем растровом редакторе, а если описывают, то в очень общем, действительно сложном изводе. Для короткого, но познавательного изучения растровых форматов на занятиях по программированию большинство библиотек непригодны — получится изучение самих библиотек.
Байты и договоренности
Чего не хватает — это наглядного представления изображения в виде двумерного массива байтов и сопутствующей информации. Например, в «проекте рисования графика» мы использовал для этой цели… двумерный массив байтов! Более точно — массив строк, каждый символ которых соответствует отдельной точке «экрана». Обновление такого «экрана» — просто вывод всех строк на текстовый терминал.
Довольно интересный компромисс в этом плане — формат X Pixmap.
Вот, например, маленькая картинка в формате xpm: А вот тот же самый файл непосредственно:
1 static char * rbomb_xpm[] = {
2 /* width height ncolors chars_per_pixel */
3 "32 32 5 1",
4 /* colors */
5 " c None s Transparent",
6 "o c gray50 s Cord",
7 "O c black",
8 "$ c red",
9 "% c #D0D0A0 s Gold",
10 /* pixels */
11 " ",
12 " ",
13 " ",
14 " ",
15 " ",
16 " ",
17 " ",
18 " ",
19 " oOoOo ",
20 " O Oo ",
21 " o O ",
22 " O o ",
23 " OOOOO O ",
24 " OOOOO o ",
25 " OOOOOOO O ",
26 " oOOOOOOOOOo o $ $",
27 " oOOOOOOOOOOOo O $ $ ",
28 " oOOOOOOOOOOOOOo o $ ",
29 " OOOOOOOO%ooOOOO O $ $ ",
30 " oOOOOOOOOO%ooOOOo o $ $ ",
31 " OOOOOOOOOOOOOOOOO OoO $ $ $",
32 " OOOOOOOOOOO%ooOOO $$ ",
33 " OOOOOOOOOOO%ooOOO $ $ ",
34 " OOOOOOOOOOO%ooOOO $ $ ",
35 " OOOOOOOOOOOOOOOOO $ ",
36 " oOOOOOOOOOOOOOOOo $ $ $",
37 " OOOOOOOOOOOOOOO ",
38 " oOOOOOOOOOOOOOo $ ",
39 " oOOOOOOOOOOOo ",
40 " oOOOOOOOOOo ",
41 " oOOOOOo ",
42 " "};
То есть сам формат — строго текстовый. Зная структуру XPM-файла, его несложно создать, и ещё проще — редактировать в произвольном текстовом редакторе.
Нетрудно заметить, что XPM-файл — это просто массив строк, записанный на языке программирования Си. Первая строка массива содержит (в строковом виде) метаинформацию: ширину и высоту картинки в точках растра, количество цветов в палитре и «количество символов на цвет». Вот этот последний параметр особенно забавен: дело в том, что последние строки XPM-файла представляют собственно изображение, причём одна точка растра соответствует фиксированному числу символов (удобнее всего, когда одному). При этом сами символы задаются произвольно в палитре, начинающейся со второй строки массива. В частности, в примере чёрному цвету соответствует символ 'O', а красному — '$'.
Цвета в палитре можно задавать в пространстве RBG (24 бита на точку), как это сделано для золотистого цвета, а можно по именам. Имена цветов X.Org (графической подсистеме, используемой в большинстве дистрибутивов Linux) заданы примерно в том же формате в файле /usr/share/X11/rgb.txt. Среди них встречаются весьма поэтично названные, например LavenderBlush или PeachPuff.
Ещё одна особенность XPM — «значимые» имена цветов (задаются в форме «s имя»); в примере значимые имена даны всем цветам, кроме красного и чёрного. Соответствующая библиотека (libxpm) позволяет программам работать с этими значащими именами вместо непосредственно символов, так что нет необходимости пользоваться ровно теми символами, которые заданы в палитре. Например, при разработке графического интерфейса можно выделить цвет фона, цвет печати, цвета обычной, затенённой и высветленной областей границы и т. п. «Кнопочка» будет нарисована независимо от того, какая в действительности задана палитра. Но и без библиотеки такие имена полезны — они указывают на назначение цвета. При описании цвета можно ещё задавать, как отображать точки этого цвета в монохромном и чёрно-белом пространстве (когда-то давно это было насущной необходимостью, т. к. далеко не все графические устройства были цветными).
Одно из имён цвета — «None» — особенное. Это не значащее имя, а именно задание цвета (значащее имя для цвета None в примере — Transparent). При обработке изображения точки цвета None считаются прозрачными, выводятся и обрабатываются соответственно.
Дальнейшее обсуждение формата выходит за рамки интересного, можно поизучать соответствующую документацию.
TODO X Pixmap
Что в итоге
При всё своей «игрушечности» формат XPM:
- На самом деле никакой не игрушечный
- Долгое время был чуть ли не де-факто стандартом на маленькие изображения в графической системе X.org
Правда, броузеры его показывать отказываются
- Позволяет сразу зацепить несколько тем:
Растр как матрица точек + дополнительная информация
- Представление цветов в пространстве RGB и именование
- Палитрованое изображение
- Абстракции «прозрачность», «цвет фона», «цвет рисования»
- Работа с точками растра при преобразовании
Неплохо подходит для изучения в курсе программирования на Си