引言
delphi是目前廣泛使用的可視化開(kāi)發(fā)工具,它自身帶有一個(gè)圖片、
圖標(biāo)的編輯器——Image Editor,但是到
delphi7為止,都不能進(jìn)行真彩
圖標(biāo)的編輯,可以說(shuō)是一個(gè)遺憾。筆者通過(guò)對(duì)
圖標(biāo)文件的研究,實(shí)現(xiàn)了產(chǎn)生
24位真彩色
圖標(biāo)。
圖標(biāo)文件的格式 首先,分析一個(gè)具體的
圖標(biāo) 。在CS1.6中有一個(gè)
圖標(biāo)game.ico( ),如果用WinHex等可以進(jìn)行16進(jìn)制編輯的
軟件打開(kāi)這個(gè)
圖標(biāo)文件,我們可以看到如下數(shù)據(jù):
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
下面我們就說(shuō)一說(shuō),這些數(shù)據(jù)的具體含義。一個(gè)
圖標(biāo)文件(*.ICO),實(shí)際上可以含有多個(gè)
圖標(biāo).通常,每個(gè)
圖標(biāo)都會(huì)被轉(zhuǎn)換為針對(duì)特定
顯示設(shè)備的
圖標(biāo)圖像。
圖標(biāo)文件由文件頭和數(shù)據(jù)組成, ICO文件一開(kāi)始,是一個(gè)叫做tagIconDir的記錄型的結(jié)構(gòu),在
delphi中這樣來(lái)描述(括號(hào)內(nèi)的數(shù)值,是針對(duì)CS
圖標(biāo)的具體數(shù)據(jù)):
tagIconDir = packed record idReserved:WORD;// 保留域,目前始終為 0(開(kāi)始的數(shù)據(jù) 00) idType:WORD; //定義為資源類型,圖標(biāo)值為 01、光標(biāo)是02(01) idCount:WORD; //idCount 表示的是這個(gè)文件里包含了幾個(gè)圖標(biāo)(04) idEntries:array[0..0] of tagIconDirEntry; //不包括本數(shù)組,以上一共6個(gè)字節(jié) end; |
這個(gè)記錄中的idEntries 是個(gè)數(shù)組結(jié)構(gòu),這個(gè)結(jié)構(gòu)的大小不是始終為 1 的一個(gè)數(shù)組,它需要根據(jù)
圖標(biāo)數(shù)目 ( idCount ) 來(lái)確定真實(shí)的數(shù)組大小。它的類型為tagIconDirEntry記錄,定義如下:
tagIconDirEntry = packed record bWidth:BYTE;// 圖標(biāo)圖片的顯示寬度,以像素為單位,最大值為255 (=16D) bHeight:BYTE;// 圖標(biāo)圖片的顯示高度,以像素為單位,最大值為255 (=16D) bColorCount:BYTE;// 圖標(biāo)圖片的顏色數(shù)() bReserved:BYTE;// 保留域總是 0 () wPlanes:WORD;// 圖標(biāo)圖片的位面數(shù) ( 00) wBitCount:WORD;// 圖標(biāo)圖片的顏色深度( 00) dwBytesInRes:DWORD;// 圖標(biāo)圖片占用的數(shù)據(jù)量(000568) dwImageOffset:DWORD; // 圖標(biāo)圖片的開(kāi)始位置 (000046) end;.// 這個(gè)結(jié)構(gòu)是16個(gè)字節(jié) |
上面說(shuō)的idCount 表示
圖標(biāo)文件里包含的
圖標(biāo)個(gè)數(shù),每個(gè)
圖標(biāo)都要有一個(gè)tagIconDirEntry結(jié)構(gòu)來(lái)表示
圖標(biāo)的具體信息。根據(jù)本結(jié)構(gòu)的dwBytesInRes和dwImageOffset我們就可以確定圖片(
圖標(biāo))的位置了。在該位置的數(shù)據(jù)是一個(gè)稱為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; |
從這個(gè)定義中我們可以看出,這個(gè)內(nèi)容就是一個(gè)標(biāo)準(zhǔn)的位圖格式,只不過(guò)多了兩項(xiàng),icXOR和icAND,普通的位圖信息里是沒(méi)有這2 個(gè)成員的。大家知道,
圖標(biāo)在被顯示時(shí),是利用遮罩方法將 2 副位圖在同一個(gè)位置顯示才產(chǎn)生任意輪廓的,先使用 XOR 位 圖摳出需要顯示的區(qū)域,然后再在摳出的區(qū)域中顯示出需要顯示的圖形。由于這個(gè)緣故,
圖標(biāo)的位圖格式中的位圖信息頭 ( TBitmapInfoHeader ) 是 2 個(gè)位圖共用 的。它與普通位圖頭信息最大的不同是 TBitmapInfoHeader.biHeight 成員,顯然它是 2 副位圖高度的總和。講到這里,我們需要對(duì)位圖(BMP)文件的格式有些了解了。
位圖文件的格式 BMP文件由文件頭、位圖信息頭、顏色信息和圖形數(shù)據(jù)四部分組成。按照微軟的定義,在開(kāi)始的文件頭由14個(gè)字節(jié)組成:
tagBITMAPFILEHEADER= packed record bfType:WORD; // 位圖文件的類型,必須為BM bfSize:DWORD; // 位圖文件的大小,以字節(jié)為單位 bfReserved1:WORD; // 位圖文件保留字,必須為0 bfReserved2:WORD; // 位圖文件保留字,必須為0 bfOffB its:DWORD; // 位圖數(shù)據(jù)的起始位置,以相對(duì)于位圖 // 文件頭的偏移量表示,以字節(jié)為單位 End; |
緊接著上一記錄的是位圖信息頭tagBITMAPINFOHEADER,BMP位圖信息頭數(shù)據(jù)用于說(shuō)明位圖的尺寸等信息。這個(gè)信息頭就是上文說(shuō)的TBitmapInfoHeader,它的長(zhǎng)度固定為40字節(jié)。
tagBITMAPINFOHEADER= packed record biSize:DWORD; // 本結(jié)構(gòu)所占用字節(jié)數(shù) biWidth:LONGINT // 位圖的寬度,以像素為單位 biHeight; :LONGINT // 位圖的高度,以像素為單位 biPlanes; :WORD // 目標(biāo)設(shè)備的級(jí)別,必須為1 biBitCount :WORD // 每個(gè)像素所需的位數(shù),必須是1(雙色), // 4(16色),8(256色)或24(真彩色)之一 biCompression :DWORD; // 位圖壓縮類型,必須是 0(不壓縮), // 1(BI_RLE8壓縮類型)或2(BI_RLE4壓縮類型)之一 biSizeImage :DWORD; // 位圖的大小,以字節(jié)為單位 biXPelsPerMeter:LONGINT; // 位圖水平分辨率,每米像素?cái)?shù) biYPelsPerMeter:LONGINT; // 位圖垂直分辨率,每米像素?cái)?shù) biClrUsed:DWORD;// 位圖實(shí)際使用的顏色表中的顏色數(shù) biClrImportant:DWORD;// 位圖顯示過(guò)程中重要的顏色數(shù) End; |
緊接著就是顏色表,用于說(shuō)明位圖中的顏色,它有若干個(gè)表項(xiàng),每一個(gè)表項(xiàng)是一個(gè)RGBQUAD類型的結(jié)構(gòu),定義一種顏色。RGBQUAD結(jié)構(gòu)的定義如下:
tagRGBQUAD = packed record rgbBlue:BYTE;// 藍(lán)色的亮度(值范圍為0-255) rgbGreen:BYTE; // 綠色的亮度(值范圍為0-255) rgbRed:BYTE; // 紅色的亮度(值范圍為0-255) rgbReserved:BYTE;// 保留,必須為0 end; |
顏色表中RGBQUAD結(jié)構(gòu)數(shù)據(jù)的個(gè)數(shù)有biBitCount來(lái)確定:
當(dāng)biBitCount=1,4,8時(shí),分別有2,16,256個(gè)表項(xiàng);
當(dāng)biBitCount=24時(shí),沒(méi)有顏色表項(xiàng)。
位圖信息頭和顏色表組成位圖信息,BITMAPINFO結(jié)構(gòu)定義如下:
tagBITMAPINFO = packed record bmiHeader :BITMAPINFOHEADER; // 位圖信息頭 bmiColors[0..0] :RGBQUAD; // 顏色表 End; |