1. 程式人生 > >Icon圖示格式(用於生成*.ico圖示)

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時有效位填不滿,空出