bool HBITMAPToBmp(HBITMAP hBitmap, const CString & strFileName
)
{
if(hBitmap == NULL
)
return false
;
HDC hDC
;
int iBits;
//当前分辨率下每象素所占字节数
WORD wBitCount;
//位图中每象素所占字节数
DWORD dwPaletteSize=0;
//定义调色板大小
DWORD dwBmBitsSize=0;
//位图中像素字节大小
DWORD dwDIBSize=0;
//位图文件大小
DWORD dwWritten=0;
//位图文件大小 写入文件字节数
BITMAP Bitmap;
//位图属性结构
BITMAPFILEHEADER bmfHdr;
//位图文件头结构
BITMAPINFOHEADER bi;
//位图信息头结构
LPBITMAPINFOHEADER lpbi = NULL;
//指向位图信息头结构
HANDLE hDib, hPal, hOldPal = NULL;
//定义文件,分配内存句柄,调色板句柄
//计算位图文件每个像素所占字节数
hDC = CreateDC(_T("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
wBitCount
= 24;
GetObject(hBitmap, sizeof(Bitmap),(LPSTR)&Bitmap
);
bi.biSize = sizeof(BITMAPINFOHEADER
);
bi.biWidth = Bitmap.bmWidth
;
bi.biHeight = Bitmap.bmHeight
;
if(Bitmap.bmWidth < 100 || Bitmap.bmHeight
< 100)
return false
;
bi.biPlanes
= 1;
bi.biBitCount = wBitCount
;
bi.biCompression = BI_RGB
;
bi.biSizeImage
= 0;
bi.biXPelsPerMeter
= 0;
bi.biYPelsPerMeter
= 0;
bi.biClrImportant
= 0;
bi.biClrUsed
= 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
);
}
//获取该调色板下新的像素值
int nRet = GetDIBits(hDC
,
hBitmap
,
0, (
UINT)Bitmap.bmHeight
,
(
LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize
,
(
BITMAPINFO *)lpbi
,
DIB_RGB_COLORS
);
if (0 == nRet
)
{
nRet
= 0;
}
//恢复调色板
if(hOldPal
)
{ ::
SelectPalette(hDC, (HPALETTE)hOldPal,TRUE
);
RealizePalette(hDC
);
::
ReleaseDC(NULL,hDC
);
}
//设置位图文件头
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
;
//创建位图文件
HANDLE fh = CreateFile(strFileName.operator LPCTSTR(), GENERIC_WRITE,0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL
);
if (fh == INVALID_HANDLE_VALUE
)
{
int x = GetLastError
();
GlobalUnlock(hDib
);
GlobalFree(hDib
);
return FALSE
;
}
//写入位图文件头
WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten,NULL
);
//写入位图文件其余内容
WriteFile(fh, (LPSTR)lpbi, dwDIBSize - sizeof(BITMAPFILEHEADER), &dwWritten, NULL
);
//清除
CloseHandle(fh
);
GlobalUnlock(hDib
);
GlobalFree(hDib
);
return true
;
}