void SaveBitmapToFile(HBITMAP hBitmap, char* szfilename)
{
HDC hdc; //设备描述表
int ibits;
WORD wbitcount; //当前显示分辨率下每个像素所占字节数
//位图中每个像素所占字节数,定义调色板大小,位图中像素字节大小,位图文件大小 ,写入文件字节数
DWORD dwpalettesize = 0, dwbmbitssize, dwdibsize, dwwritten;
BITMAP bitmap; //位图属性结构
BITMAPFILEHEADER bmfhdr; //位图文件头结构
BITMAPINFOHEADER bi; //位图信息头结构
LPBITMAPINFOHEADER lpbi; //指向位图信息头结构
//定义文件,分配内存句柄,调色板句柄
HANDLE fh, hdib, hpal, holdpal = NULL;
//计算位图文件每个像素所占字节数
hdc = CreateDC("display", NULL, NULL, NULL);
ibits = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
DeleteDC(hdc);
if (ibits <= 1)
wbitcount = 1;
else if (ibits <= 4)
wbitcount = 4;
else if (ibits <= 8)
wbitcount = 8;
else if (ibits <= 16)
wbitcount = 16;
else if (ibits <= 24)
wbitcount = 24;
else
wbitcount = 32;
//计算调色板大小
if (wbitcount <= 8)
dwpalettesize = (1 << wbitcount) * sizeof(RGBQUAD);
//设置位图信息头结构
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bitmap.bmWidth;
bi.biHeight = bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wbitcount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwbmbitssize = ((bitmap.bmWidth * wbitcount + 31) / 32) * 4 * bitmap.bmHeight;
//为位图内容分配内存
hdib = GlobalAlloc(GHND, dwbmbitssize + dwpalettesize + sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
*lpbi = bi;
// 处理调色板
hpal = GetStockObject(DEFAULT_PALETTE);
if (hpal)
{
hdc = ::GetDC(NULL);
holdpal = SelectPalette(hdc, (HPALETTE)hpal, false);
RealizePalette(hdc);
}
// 获取该调色板下新的像素值
GetDIBits(hdc, hBitmap, 0, (UINT)bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) + dwpalettesize, (BITMAPINFO*)lpbi, DIB_RGB_COLORS);
//恢复调色板
if (holdpal)
{
SelectPalette(hdc, (HPALETTE)holdpal, true);
RealizePalette(hdc);
::ReleaseDC(NULL, hdc);
}
//创建位图文件
fh = CreateFile(szfilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE)
return false;
// 设置位图文件头
bmfhdr.bfType = 0x4d42; // "bm"
dwdibsize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
dwpalettesize + dwbmbitssize;
bmfhdr.bfSize = dwdibsize;
bmfhdr.bfReserved1 = 0;
bmfhdr.bfReserved2 = 0;
bmfhdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) +
(DWORD)sizeof(BITMAPINFOHEADER) + dwpalettesize;
//写入位图文件头
WriteFile(fh, (LPSTR)&bmfhdr, sizeof(BITMAPFILEHEADER), &dwwritten, NULL);
//写入位图文件其余内容
WriteFile(fh, (LPSTR)lpbi, dwdibsize, &dwwritten, NULL);
//清除
GlobalUnlock(hdib);
GlobalFree(hdib);
CloseHandle(fh);
}