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