ICO文件格式的演化(二):彩色图标
原文:http://blogs.msdn.com/b/oldnewthing/archive/2010/10/19/10077610.aspx
上次,我们说了单色图标。那么彩色图标是怎么样的呢?(一个ICO中同时包含单色和彩色的图标是合法的。为什么不支持2色的图标呢?毕竟ICO文件是支持16色或高彩色(译注:16位色)的图标的。)
ICO中的彩色图像和单色图像的格式基本上的一样的。唯一的区别就是image位图是彩色的了。(mask依然是单色的。)(译注:无论image部分是多少bpp的像素,mask永远是1bpp。并且每行像素的数据必须是4字节对齐的。例如:48*48大小的16色图标,像素部分的数据大小是1536字节,你们可以算一下为什么是这样?)
也就是说,图像格式包含一个BITMAPINFOHEADER,其中bmWidth是图像的宽度,bmHeight是图像宽度的两倍。接着是调色板、image像素的数据和mask像素的数据。
要注意到的是,这并不是一个标准的位图格式。因为同时包含了image和mask,所以高度是两倍。但是,像素的格式在中间的时候改变了。
还有个限制:只支持4bpp、8bpp、16bpp和0RGB 32bpp,而不支持24bpp。对于彩色图标,biCompression支持BI_RGB和BI_BITFIELDS(如果位图是16bpp或32bpp)。
绘制图标的机制和单色图标是一样的:首先mask和screen与,然后和image异或。也就是说:
pixel = (screen AND mask) XOR image
然而对于彩色像素来说,异或操作并不是有意义的操作。并不是通常所说的“谁都知道,紫红异或浅绿等于黄色。”或者“在8bpp上,蓝色异或淡黄褐色等于杏黄色(因为淡黄褐色在调色板的索引是56,蓝色的索引是1,而索引57的颜色是杏黄色),而在32bpp上等于#F0EA29”。唯一有意义的是和黑色作异或,你会得到“对于任意颜色Q来说,黑色 XOR Q = Q”。
mask | image | 结果 | 操作 |
0 | Q | (screen AND 0) XOR Q = Q | 图标的像素 |
1 | 0 | (screen AND 1) XOR 0 = screen | 不变 |
1 | Q | (screen AND 1) XOR Q = screen XOR Q | 不确定 |
要使像素透明,你要把mask设置成白色,并且image为黑色。而要使用来自于图标中的像素,则mask设置成黑色,image的颜色设置成你想要的随便什么颜色。
扩展阅读:Icons in Win32