![]() |
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]() ![]() ![]() |
|
ManiaK |
|
||||||||||||||||
![]() Homo Sapience ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1145 Регистрация: 3.8.2004 Где: ИУ5-93 Репутация: 2 Всего: 29 |
Статья написана мной чёрт знает в каком году. В ней есть несколько неточностей, однако в целом она мне показалась интересной. Решил запостить, мало ли - пригодиться.
32-битные иконки: закат солнца вручную С каждой новой версией операционная система Microsoft Windows® становится всё нарядней и нарядней. Как только не ухитряются сотрудники известной компании, какие только игрушки не навешивают на неё, забывая порой, что скорость и надёжность работы программ ценится куда выше, чем внешний вид... Но оставим философствования и упреки тем, кто по профессии призван заниматься ими; у нас же слишком мало на то времени... Итак, с выходом Windows XP, столь широко распространённые значки стали просто неописуемы! - в них, наконец, добавили функции прозрачности. Но не заметили ли вы чего-нибудь странного? Почему эти полупрозрачные значки не открываются нашими стандартными функциями? большинство программ по их редактированию вообще не хотят читать их, а те немногие, что шагнули вместе с системой, как правило, требуют немалых денег для использования. Но ладно, сделаем вид, что не заметили.. В новой версии программы радостно пишем код, загружающий иконки со стандартных Windows-приложений, запускаем... дулю! WinAPI только ехидно посмеётся над вами и в лучшем случае нарисует нечто отдалённо похожее на оригинал, но окружённое чёрными пятнами.. не узнаёте ситуацию? Что ж это получается - монополия? Неужели корпорация майкрософт, не без пафоса будь сказано, таким образом думает оказаться заранее на более высокой планке, чем все сторонние разработчики? Смешно! Реакция этой гиганской софтверной компании похожа на реакцию маленького ребёнка, который старается поломать песочный домик приятеля, только чтобы казаться окружающим единственным и неповторимым!.. Страшно сказать, но эта детская логика оказывается действенна - не раз я сам из двух более-менее схожих по возможностям программ выбирал именно ту, в которой красивее нарисованы кнопочки, менюшки, иконки... Иногда так и хочется задать вопрос компании: может вам вообще сторонние программисты не нужны? Глядя на цены Dev-пакетов + внезапно возросший интерес компании к языкам "сверхвысокого" уровня, идея эта перестаёт почему-то казаться бредовой: на .NET оси не напишешь!.. Но бог с ней - с политикой. Нам иконки нужны, по-красивей и побольше! Спокойствие, если нам не дают возможность отображать в наших программах полупрозрачные иконки... мы возьмём её сами!.. Формат ICO (как и CUR) не представляет из себя ничего особенного. Всё представление можно разбить на пару структур, вложенных друг в друга. Спускаясь как бы сверху вниз, разберём строение файла и способ его рисования. Итак, на самом "высоком" уровне находятся только две структуры:
Число элементов ICONIMAGE равно числу пиктограмм, находящихся в файле. Структура ICONHEADER представляет собой нечто вроде каталога пиктограмм:
ihReserved - не понимаю, зачем нужны подобные "резервы"; данный байт по идее должен быть равен нулю, но не советую полагаться на это... ihType - тип файла; 1 - иконка, 0 - курсор. ihCount - количество пиктограм, находящихся в файле. ihEntries - массив описаний пиктограмм; как не трудно догадаться, число элементов массива равно ihCount. ICONDIRENTRY содержит в себе размеры изображения, число цветов и ещё пару переменных, которые включены в формать только для удобства:
bWidth и dHeight содержат длину и ширину файла; надо заметить, это не единственные размерные величины, но самые верные - если они не соответствуют действительному размеру, файл испорчен. bColorCount указывает на количество цветов пиктограммы; бесполезнейшая штука, так как в 24-32 разрядных режимах количество всех доступных цветов в один байт не уместится - да и надо ли оно?!.. dwBytesInRes, следуя книге 95-го года, содержит размер в байтах ресурса пиктограммы, который состоит из всех пиктограмм файла минус ICONHEADER; логичней было бы сделать просто размер данной пиктограммы в байтах... dwImageOffset - байтовое смещение до начала изображения пиктограммы, начиная от начала файла. Теперь пришло время описать структуру самого изображения пиктограммы:
icHeader содержит в себе информацию о данной пиктограмме; как и RGBQUAD, структура определена в стандартных windows-заголовочных файлах; вот, что она собой представляет:
Не поленюсь и объясню все переменные структуры, хотя большинство из них совершенно бесполезны. biWidth - формально ширина изображения в пикселях; на практике может быть что угодно, лучше не пользоваться... biHeight - формально высота изображения; см. выше... biPlanes - должен быть равен единице; толкового объяснения зачем это слово нужно так и не нашёл... biBitCount - число битов на пиксел. Вот эту переменную и нужно использовать при определении разрешения пиктограммы! Возможные значения: все степени двойки. На практике сейчас используются в основном 4, 8, 24, 32. biCompression - показывает, хранится ли данное растровое изображение в сжатом виде, а также метод его упаковки. BI_RGB - изображение не сжато, BI_RLE8 - восьмиразрядное групповое кодирование, BI_RLE4 - четырёхразрядное групповое кодирование. Лично я сжатых иконок не встречал, а вы?.. biSizeImage - содержит размер растрового изображения в байтах. Может быть нулевым, если изображение не сжато.. Короче: не используйте эту переменную. biXPelsPerMeter - предпочтительное разрешение по горизонтали в пикселах на метр. Чушь, не встречал использования ни разу... biYPelsPerMeter - предпочтительное разрешение по вертикали в пикселах на метр; см. выше... biClsUsed - обычно содержит число цветов, используемое в изображении и определяемое массивом iсColors типа RGBQUAD. Если равно нулю, в изображении используется максимальное количество цветов, определяемое переменной biBitCount. biClrImportant - содержит число важных цветов изображения... тьфу, ставим нуль - все цвета важные, и нечего голову ломать!.. RGBQUAD структура содержит в себе три байтовых переменные - Red, Green, Blue. Чтобы массив таких структур было удобней читать, добавлена ещё одна "резервная" байтовая переменная. Массив icColors содержит 24-битные определения цветов изображения; если biBitCount больше или равно 24 - массива icColors не существует. Соответственно, при biBitCount=8, icColors содержит 2^8=256 элементов. Теперь пришло время пояснить один момент: каким именно образом принято рисовать пиктограммы. Алгоритм следующий. Рисование изображения сильно зависит от значения переменной biBitCount. Но в любом случае рисование происходит от левого края к правому, от нижней строки, к верхней. Восьмибитное изображение в одном байте содержит 8 пикселей, расположенных на одной строке (ВНИМАНИЕ! пикселы идут от старшего разряда к младшему - момент, который пропускают почти все документации!); 24 разрядный пиксель требует 3 байт. Само изображение находится в массиве icXOR, но есть маленькая хитрость!.. Наверное не стоит объяснять, что пиктограммы имеют свойство быть как бы наклеенными на задний план: иначе говоря рисуется не весь прямоугольник, а только нужная нам картинка. Как это получается? Очень просто! Вы уже должны были обратить внимание на массив icAND, стоящий сразу за массивом пикселей изображения. Это, так называемая, маска пиктограмы. Она представляет собой чёрно-белое изображение той же длины и ширины, что и icXOR, но используется несколько иначе: единица в маске указывает на то, что изображение в данной точке не рисуется, ноль - соответственно рисуется. В 32-разрядном режиме на один пиксель приходится 4 байта, причём один из них - коэфициент прозрачности (0 - абсолютно прозрачно, 255 - абсолютно непрозрачно). Все эти хитрости легко понять на конкретном примере. Давайте попробуем написать функции, которые будут загружать иконку в оперативную память и отображать на контексте устройства (DC). Сначала определим ещё раз структуры:
Теперь пишем функцию для загрузки из файла:
Оговорюсь: я не ставлю перед собой цель дать вам готовый код, совсем нет! Я лишь объясняю логику и для большей понятности прибегаю иногда даже к неэффективности!.. Так что, оптимизация остаётся на ваших плечах... Теперь функция рисования:
Вот, кажется, и всё. Можете скомпилировать код, проверить - все 32-битные иконки будут отлично отображаться на любом фоне!.. "Где же их взять?" - скажете вы? "Нарисовать!" - отвечу я! Раз вы теперь знаете формат пиктограмм, почему бы не написать вам программку, в которой можно было бы рисовать замечательные прозрачные иконки?.. Удачного пиктограммирования!.. © 2006 Левенков Артём Алексеевич [ManiaK] |
||||||||||||||||
|
|||||||||||||||||
chipset |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4071 Регистрация: 11.1.2003 Где: Seattle, US Репутация: 2 Всего: 164 |
ООО!!! Сколько воспоминаний
![]() --------------------
|
|||
|
||||
ManiaK |
|
|||
![]() Homo Sapience ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1145 Регистрация: 3.8.2004 Где: ИУ5-93 Репутация: 2 Всего: 29 |
||||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Системное программирование и WinAPI" | |
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |