之前写程序的图标都是用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时有效位填不满,空出来的是每行后部分字节填0(自行脑补二维数组,行数相等,arr[0][0]有效arr[0][n-1]为0)),掩码部分占了width×掩码宽度 Byte
struct bitmapHeader
{
DWORD biSize;//结构长度,40Byte
LONG biWidth; //图宽度
LONG biHeight;//图高度(xor+and的)也就是两倍高度
WORD biPlanes;//我填的1
WORD biBitCount;//我填的32
DWORD biCompression;//压缩方式,填的0
DWORD biSizeImage;//图大小,仅rgba部分
LONG biXPelsPerMeter;//(后面四个貌似不用管,是属于bmp的格式),X方向分辨率
LONG biYPelsPerMeter;//Y方向分辨率
DWORD biClrUsed;//颜色数,可以填0默认
DWORD biClrImportant;//重要颜色数,填0表示全是重要
}
这样,假如是64*64的ico图标,应该占16958字节,22+40+16384+512.
自己的新电脑没有二进制查看工具,没法截图示例,有空(严重怀疑!)补上。
知道了格式就容易把图片转为ico图标了,获取rgab值然后填充字节数组就行了。