[C/C++] RGBA数组生成Windows下的ico文件

来源:互联网 发布:mac双系统怎么切换 编辑:程序博客网 时间:2024/06/05 18:36

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  72int 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;}




原创粉丝点击