Widows下只认.ico格式为程序图标,这是一种源自bmp的图片格式。ico中的颜色可以通过color table来表示也可以直接通过RGBA数组表示。
ico文件的格式见官方文档:
http://msdn.microsoft.com/en-us/library/ms997538.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/dd183376%28v=vs.85%29.aspx
其它一些关于ico文件的文档见:
比较详细的原理介绍:http://blogs.msdn.com/b/oldnewthing/archive/2010/10/18/10077133.aspx
ico格式描述:http://www.daubnet.com/en/file-format-ico
Programming Tips & Tricks:http://tipsandtricks.runicsoft.com/Cpp/BitmapTutorial.html
bmp和ico格式描述:http://www.digicamsoft.com/bmp/bmp.html
ico文件相关实现:
IconImagePlugin in Python PIL: http://code.google.com/p/casadebender/source/browse/python/PIL/Win32IconImagePlugin.py
construct ico from RGBA array - a python implementation:http://fayaa.com/code/view/6094/
png2ico:http://www.winterdrache.de/freeware/png2ico/
下面是一个用从RGBA生成ico文件的C语言实现,生成一个红色的图标文件 - test.ico。
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstdlib> #include <cstring> #include <cassert> void Fwrite(FILE * f, char * data, int byte) { if (1 != fwrite(data, byte, 1, f)) { perror("fwrite error"); exit(1); } } void WriteByte(FILE* f, unsigned int val, int byte) { char data[4]; assert(byte <= 4); memcpy((void *)data, (void *)&val, byte); Fwrite(f, data, byte); }; void generate_ico_file(const char * filename, char * body, int width, int height, int has_alpha) { int x, y; int index = 0; int Size = 0; int offset= 6 + 1 * 16; int bpp = 32; FILE* outfile=fopen(filename,"wb"); if (outfile==NULL) { perror("fopen error"); exit(1); }; WriteByte(outfile,0, 2); //idReserved WriteByte(outfile,1, 2); //idType WriteByte(outfile,1, 2); //idCount WriteByte(outfile,width, 1); //bWidth WriteByte(outfile,height, 1); //bHeight WriteByte(outfile,0, 1); //bColorCount WriteByte(outfile,0, 1); //bReserved WriteByte(outfile,1, 2); //wPlanes WriteByte(outfile,bpp, 2); //wBitCount Size = 40 + height * ((width + 31) / 32 * 32 / 8 + width * 3); //Note 4 bytes alignment if (bpp == 32) Size += height * width; WriteByte(outfile,Size, 4); //dwBytesInRes WriteByte(outfile,offset, 4); //dwImageOffset WriteByte(outfile,40, 4); //biSize WriteByte(outfile,width, 4); //biWidth WriteByte(outfile,2 * height, 4); //biHeight WriteByte(outfile,1, 2); //biPlanes WriteByte(outfile,bpp, 2); //biBitCount WriteByte(outfile,0, 4); //biCompression WriteByte(outfile,0, 4); //biSizeImage WriteByte(outfile,0, 4); //biXPelsPerMeter WriteByte(outfile,0, 4); //biYPelsPerMeter WriteByte(outfile,0, 4); //biClrUsed WriteByte(outfile,0, 4); //biClrImportant // XOR mask for (y= height - 1; y >= 0; --y) { for (x = 0; x < width; ++x) { index = (y * width + x) * 4; WriteByte(outfile, body[index], 1); //Blue WriteByte(outfile, body[index + 1], 1); //Green WriteByte(outfile, body[index + 2], 1); //Red WriteByte(outfile, has_alpha ? body[index + 3] : 255, 1); //Alpha } } // AND mask for (y = 0; y < (height * ((width + 31) / 32 * 32 / 8)); ++y) { WriteByte(outfile, 0, 1); } fclose(outfile); } #define WIDTH 72 #define HEIGHT 72 int main() { int image[WIDTH * HEIGHT]; int i, j; for (i = 0; i < HEIGHT; ++i) { for (j = 0; j < WIDTH; ++j) { image[i * WIDTH + j] = 0xFFFF0000; // pure red icon, for test } } generate_ico_file("test.ico", (char *)image, WIDTH, HEIGHT, 1); return 0; }