Icon圖示格式(用於生成*.ico圖示)
之前寫程式的圖示都是用Fireworks畫,然後線上用png轉成ico的。現在公司不能上外網了(萬惡),但是ps和fw都不能直接生成ico格式。網上找了個C#圖片轉ico的例子,不過自帶類生成的貌似格式不太好,透明圖會有黑線。於是乎就折騰了半天ico格式的協議,主要參考的是https://www.cnblogs.com/cswuyg/p/3603707.html以及他的相關參考,還有http://lqzit.iteye.com/blog/1033407。除了掩碼沒搞明白,其他基本都清楚了,然後我根據常用的那個線上轉換網站生成的格式來作為生成的格式。(其實有個開源的軟體可以直接參照那些格式,在原始碼包的coders資料夾裡有各種圖的格式,要是我早點看到就好了ImageMagick中文網:http://www.imagemagick.com.cn/download.html
廢話少說,如果要了解icon相關的協議,可以百度或者看我最上面那個連結,這裡我只寫下我的實現。生成的是32色RGBA的ico圖,在xp/win7/win10下顯示正常,沒有發現有黑線。
首先,ico圖=icon格式頭+點陣圖格式頭+imge資料(資料行是反過來的)+掩碼部分。
第一部分:icon格式頭(22Byte)
struct IconHeader
{
WORD
idReserved;
// 保留位必須為0
WORD
idType;
// 型別 (1表示icon),也就是必須為1
WORD
idCount;
// 包含多少張圖(icon可以含多張圖,分別在不同尺寸下展示)
ICONDIRENTRY idEntries[];
// 對應idCount的結構體,多少張圖就有多少個該結構
} ;
struct ICONDIRENTRY
{
BYTE
bWidth;
// 圖片的畫素寬度
BYTE
bHeight;
// 圖片的畫素高度
BYTE
bColorCount;
// 顏色深度:=1<<(wBitCount×wPlanes),如果大於等於8就為0;但是可以不管,填0就行
BYTE
bReserved;
// 保留位必須為零
WORD
wPlanes;
// Color Planes,我填的1
WORD
wBitCount;
// Bits per pixel,我填的32
DWORD
dwBytesInRes;
//該圖位元組數(點陣圖頭+image資料+掩碼的位元組總數)
DWORD
dwImageOffset;
//相對於檔案開始處的偏移量,單個圖填22,畢竟icon頭加起來22位元組
};
第二部分:點陣圖格式
struct BitmapHeader
{
BITMAPINFOHEADER icHeader;
// DIB header
RGBQUAD icColors[];
// 顏色表,24/32色不用顏色表
BYTE
icXOR[];
// DIB bits for XOR mask
BYTE
icAND[];
// DIB bits for AND mask 這兩個單色的時候位置相反
} ;
雖然後兩個xor和and沒搞懂協議怎麼算的,但是我根據生成的格式倒推出,icHeader點陣圖格式頭,40Byte;icColors去掉;icXor填圖片原始資料,並且行數是倒過來的,第一行是原圖的最後一行,以此類推,每個畫素先後填入顏色B.G.R.A部分值,共width×height×4 Byte;icAnd部分,對應不透明度,如果是透明就為1,半透明和不透明都是0(相當於1位對應於一個畫素點,行數同height,寬度若原為16/32則為掩碼佔的寬度為4Byte,若原為48/64則為8Byte,若原為128則為16Byte,並且16和48時有效位填不滿,空出