摘 要 本文详细介绍了ICO文件的格式,以及利用Jpeg、BMP等格式的24位真彩色图片,生成图标的一种方法。
关键词 图标,位图,24位真彩色
引言
Delphi是目前广泛使用的可视化开发工具,它自身带有一个图片、图标的编辑器——Image Editor,但是到Delphi7为止,都不能进行真彩图标的编辑,可以说是一个遗憾。笔者通过对图标文件的研究,实现了产生24位真彩色图标。
图标文件的格式
首先,分析一个具体的图标 。在CS1.6中有一个图标game.ico( ),如果用WinHex等可以进行16进制编辑的软件打开这个图标文件,我们可以看到如下数据:
00 00 01 00 04 00 10 10 00 00 00 00 00 00 68 05 00 00 46 00 00 00 10 10 00 00 00 00 00 00 68 03 00 00 AE 05 00 00 20 20 00 00 00 00 00 00 A8 08 00 00 16 09 00 00 20 20 00 00 00 00 00 00 A8 0C 00 00 BE 11 00 00 28 00 00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00 00 00 40 01 00 00 47 46 6C 65 6D 69 6E 67 00 01 00 00 00 00 00 00 00 00
下面我们就说一说,这些数据的具体含义。一个图标文件(*.ICO),实际上可以含有多个图标.通常,每个图标都会被转换为针对特定显示设备的图标图像。图标文件由文件头和数据组成, ICO文件一开始,是一个叫做tagIconDir的记录型的结构,在Delphi中这样来描述(括号内的数值,是针对CS图标的具体数据):
tagIconDir = packed record idReserved:WORD;// 保留域,目前始终为 0(开始的数据$00 00) idType:WORD; //定义为资源类型,图标值为 $0001、光标是$0002($0001) idCount:WORD; //idCount 表示的是这个文件里包含了几个图标($0004) idEntries:array[0..0] of tagIconDirEntry; //不包括本数组,以上一共6个字节 end; |
这个记录中的idEntries 是个数组结构,这个结构的大小不是始终为 1 的一个数组,它需要根据图标数目 ( idCount ) 来确定真实的数组大小。它的类型为tagIconDirEntry记录,定义如下:
tagIconDirEntry = packed record bWidth:BYTE;// 图标图片的显示宽度,以像素为单位,最大值为255 ($10=16D) bHeight:BYTE;// 图标图片的显示高度,以像素为单位,最大值为255 ($10=16D) bColorCount:BYTE;// 图标图片的颜色数($00) bReserved:BYTE;// 保留域总是 0 ($00) wPlanes:WORD;// 图标图片的位面数 ($00 00) wBitCount:WORD;// 图标图片的颜色深度($00 00) dwBytesInRes:DWORD;// 图标图片占用的数据量($00000568) dwImageOffset:DWORD; // 图标图片的开始位置 ($00000046) end;.// 这个结构是16个字节 |
上面说的idCount 表示图标文件里包含的图标个数,每个图标都要有一个tagIconDirEntry结构来表示图标的具体信息。根据本结构的dwBytesInRes和dwImageOffset我们就可以确定图片(图标)的位置了。在该位置的数据是一个称为agIconImage的记录,它是这样定义的:
tagIconImage = packed record icHeader:TBitmapInfoHeader; //BMP文件的信息头 icColors:array[0..0]of TRGBQuad; icXOR:array[0..0]of BYTE; icAND:array[0..0]of BYTE; end; |
从这个定义中我们可以看出,这个内容就是一个标准的位图格式,只不过多了两项,icXOR和icAND,普通的位图信息里是没有这2 个成员的。大家知道,图标在被显示时,是利用遮罩方法将 2 副位图在同一个位置显示才产生任意轮廓的,先使用 XOR 位 图抠出需要显示的区域,然后再在抠出的区域中显示出需要显示的图形。由于这个缘故,图标的位图格式中的位图信息头 ( TBitmapInfoHeader ) 是 2 个位图共用 的。它与普通位图头信息最大的不同是 TBitmapInfoHeader.biHeight 成员,显然它是 2 副位图高度的总和。讲到这里,我们需要对位图(BMP)文件的格式有些了解了。
位图文件的格式
BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。按照微软的定义,在开始的文件头由14个字节组成:
tagBITMAPFILEHEADER= packed record bfType:WORD; // 位图文件的类型,必须为BM bfSize:DWORD; // 位图文件的大小,以字节为单位 bfReserved1:WORD; // 位图文件保留字,必须为0 bfReserved2:WORD; // 位图文件保留字,必须为0 bfOffB its:DWORD; // 位图数据的起始位置,以相对于位图 // 文件头的偏移量表示,以字节为单位 End; |
紧接着上一记录的是位图信息头tagBITMAPINFOHEADER,BMP位图信息头数据用于说明位图的尺寸等信息。这个信息头就是上文说的TBitmapInfoHeader,它的长度固定为40字节。
tagBITMAPINFOHEADER= packed record biSize:DWORD; // 本结构所占用字节数 biWidth:LONGINT // 位图的宽度,以像素为单位 biHeight; :LONGINT // 位图的高度,以像素为单位 biPlanes; :WORD // 目标设备的级别,必须为1 biBitCount :WORD // 每个像素所需的位数,必须是1(双色), // 4(16色),8(256色)或24(真彩色)之一 biCompression :DWORD; // 位图压缩类型,必须是 0(不压缩), // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 biSizeImage :DWORD; // 位图的大小,以字节为单位 biXPelsPerMeter:LONGINT; // 位图水平分辨率,每米像素数 biYPelsPerMeter:LONGINT; // 位图垂直分辨率,每米像素数 biClrUsed:DWORD;// 位图实际使用的颜色表中的颜色数 biClrImportant:DWORD;// 位图显示过程中重要的颜色数 End; |
紧接着就是颜色表,用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:
tagRGBQUAD = packed record rgbBlue:BYTE;// 蓝色的亮度(值范围为0-255) rgbGreen:BYTE; // 绿色的亮度(值范围为0-255) rgbRed:BYTE; // 红色的亮度(值范围为0-255) rgbReserved:BYTE;// 保留,必须为0 end; |
颜色表中RGBQUAD结构数据的个数有biBitCount来确定:
当biBitCount=1,4,8时,分别有2,16,256个表项;
当biBitCount=24时,没有颜色表项。
位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:
tagBITMAPINFO = packed record bmiHeader :BITMAPINFOHEADER; // 位图信息头 bmiColors[0..0] :RGBQUAD; // 颜色表 End; |
<  
1/2 1 2 下一页 尾页 |