|
#define ICON_SIZE 32
static int _HBitmapToBmp32Bits(HBITMAP hBitmap, U8 *out, int out_len) { /**//* * 注意: * 该函数代码部分参考csdn。向原作者致敬! */ // 设备描述表 HDC hDC; //位图中每个像素所占字节数 WORD wBitCount; // 定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数 DWORD dwBmBitsSize; //位图属性结构 BITMAP Bitmap; //位图信息头结构 BITMAPINFOHEADER bi; // 定义文件,分配内存句柄,调色板句柄 // 计算位图文件每个像素所占字节数 HANDLE hPal, hOldPal = NULL;
// 设置位图信息头结构 wBitCount = 32; GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap); if (Bitmap.bmWidth != ICON_SIZE || Bitmap.bmHeight != ICON_SIZE) { Dbg("size not fit\n"); return 0; }
memset(&bi, 0, sizeof(bi)); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = Bitmap.bmWidth; bi.biHeight = Bitmap.bmHeight; bi.biPlanes = 1; bi.biBitCount = wBitCount; bi.biCompression = BI_RGB;
// 计算位图大小 dwBmBitsSize = ((Bitmap.bmWidth*wBitCount+31)/32) * 4 * Bitmap.bmHeight; if (out_len < (int)dwBmBitsSize) return 0;
// 处理调色板 hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE); if (hPal) { hDC = GetDC(NULL); hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE); RealizePalette(hDC); }
// 获取该调色板下新的像素值 GetDIBits(hDC, hBitmap, 0, (UINT)Bitmap.bmHeight, (LPSTR)out, (BITMAPINFO *)&bi, DIB_PAL_COLORS );
// 恢复调色板 if (hOldPal) { SelectPalette(hDC,(HPALETTE)hOldPal, TRUE); RealizePalette(hDC); ReleaseDC(NULL, hDC); }
return dwBmBitsSize; }
static int ExtToIcoFile(char *ext, U8 *out, int out_len) { SHFILEINFOA sfi; char str[32] = { "*." }; U32 *buf; ICONINFO ii; U8 *orig = out; int i;
#define XOR_SIZE ICON_SIZE*ICON_SIZE*4 #define AND_SIZE ICON_SIZE*ICON_SIZE/8
// Calc File Length // 文件头6字节 // 图像信息块16字节 // BMP信息头40字节 // XOR位图 // 单色AND位图 if (out_len < 6 + 16 + 40 + XOR_SIZE + AND_SIZE) return 0;
strncat(str, ext, sizeof(str) - 8); SHGetFileInfoA(str, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(SHFILEINFO), SHGFI_USEFILEATTRIBUTES | SHGFI_ICON ); GetIconInfo(sfi.hIcon, &ii);
/**//* (一、文件头6字节) 000(000)2 保留的字节 00 00 002(002)2 资源类型 01 00 (01为图标,02为光标) 004(004)2 图象个数 01 00 */ *(U16 *)out = 0; out += 2; *(U16 *)out = 1; out += 2; *(U16 *)out = 1; out += 2;
/**//* (二、图像信息块16字节) 006(006)1 图标宽度 20 007(007)1 图标高度 20 008(008)1 颜色计数 00(02=单色, 00≥256色) 009(009)1 未用 00 010(00A)4 保留的 00 00 00 00 014(00E)4 图象数据块的长度 28 01 00 00(10进制=296) 018(012)4 图象数据块相对于文件头部的偏移量 16 00 00 00(10进制=22) */ *out++ = ICON_SIZE; *out++ = ICON_SIZE; *out++ = 0; *out++ = 0; *(U32 *)out = 0; out += 4; *(U32 *)out = 40 + XOR_SIZE + AND_SIZE; out += 4; *(U32 *)out = 22; out += 4;
/**//* (三、BMP信息头40字节) 022(016)4 BMP 信息头结构长度 28 00 00 00(10进制=40) 026(01A)4 图像宽度 10 00 00 00 030(01E)4 图像高度(XOR图高度+AND图高度) 20 00 00 00 034(022)2 位面板数 01 00 036(024)2 每象素所占位数 04 00 038(026)4 象素数据的压缩类型 00 00 00 00(表示未压缩) 042(02A)4 图象数据的长度 C0 00 00 00(10进制=192) 046(02E)16 未用 16个00 */ *(U32 *)out = 40; out += 4; *(U32 *)out = 32; out += 4; *(U32 *)out = 64; out += 4; *(U16 *)out = 1; out += 2; // ?? *(U16 *)out = 32; out += 2; *(U32 *)out = 0; out += 4; *(U32 *)out = XOR_SIZE + AND_SIZE; out += 4; memset(out, 0, 16); out += 16;
/**//* (五、XOR位图的数据) */ if (_HBitmapToBmp32Bits(ii.hbmColor, out, XOR_SIZE) != XOR_SIZE) return 0; out += 32*32*4;
/**//* (六、单色AND位图的数据) */ buf = (U32 *)malloc(XOR_SIZE); if (!buf) return 0; if (_HBitmapToBmp32Bits(ii.hbmMask, (U8 *)buf, XOR_SIZE) != XOR_SIZE) return 0; memset(out, 0, AND_SIZE); //out += 32*32/8; for (i = 0; i < AND_SIZE*8; i++) { if (buf[i]) *out |= (1 << (7 - (i&7))); if ((i&7) == 7) out++; } free(buf);
#undef AND_SIZE #undef XOR_SIZE
return out - orig; }
#undef ICON_SIZE
int main() { void *s, *a; int len; static char line[1024], method[16], url[128]; FILE *fp; static U8 buf[1024*1024*1]; fp = fopen("b.ico", "wb+"); len = ExtToIcoFile("mp3", buf, sizeof(buf)); len = fwrite(buf, len, 1, fp); fclose(fp); return 0;
|