|
#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;

|