步骤:
1 初始化BITMAPINFOHEADER数据结构。 用位图信息决定位图的宽高与字节数。最好使用BI_RGB压缩。
2 实现并选择逻辑调色板。
3 决定位图使用的字节数。首先为BITMAPINFOHEADER和颜色表分配内存,然后调用GetDIBits()去计算位图字节数。
4 给最终的位图尺寸分配内存块,包括BITMAPINFOHEADER和颜色表与位图字节数。
5 最终再调用GetDIBits()得到位图的字节数。
HANDLE DDBToDIB( CBitmap& bitmap, DWORD dwCompression, CPalette* pPal )
{
ITMAP m;
ITMAPINFOHEADER i;
PBITMAPINFOHEADER pbi;
WORD wLen;
ANDLE DIB;
ANDLE andle;
DC DC;
PALETTE hPal;
ASSERT( bitmap.GetSafeHandle() );
//这个函数没有BI_BITFIELDS参数
if( dwCompression == BI_BITFIELDS )
return NULL;
// 如果没有提供调色板,则使用缺省调色板
hPal = (HPALETTE) pPal->GetSafeHandle();
if (hPal==NULL)
hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
// 得到位图信息
bitmap.GetObject(sizeof(bm),(LPSTR)&bm);
// 初始化BITMAPINFOHEADER
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight= bm.bmHeight;
bi.biPlanes= 1;
bi.biBitCount= bm.bmPlanes * bm.bmBitsPixel;
bi.biCompression=dwCompression;
bi.biSizeImage= 0;
bi.biXPelsPerMeter=0;
bi.biYPelsPerMeter=0;
bi.biClrUsed= 0;
bi.biClrImportant=0;
//计算infoheader和色彩表的大小
int nColors = (1 << bi.biBitCount);
if( nColors > 256 )
nColors = 0;
dwLen = bi.biSize + nColors * sizeof(RGBQUAD);
// 得到DIB所需的句柄
hDC = GetDC(NULL);
hPal = SelectPalette(hDC,hPal,FALSE);
RealizePalette(hDC);
// 分配内存以容纳BITMAPINFOHEADER和色彩表
hDIB = GlobalAlloc(GMEM_FIXED,dwLen);
if (!hDIB)
{
SelectPalette(hDC,hPal,FALSE);
ReleaseDC(NULL,hDC);
return NULL;
lpbi = (LPBITMAPINFOHEADER)hDIB;
*lpbi = bi;
//将NULL作为lpvBits项的参数调用GetDIBits()函数
//该函数将会计算BITMAPINFOHEADER的biSizeImage域
GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
bi = *lpbi;
// 如果该函数没有填写biSizeImage域,则计算它
// 每行象素必须占用4字节的整数倍(32位)。
if (bi.biSizeImage == 0)
{
bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
* bi.biHeight;
// 如果压缩方式使文件变得更大,那么必须增大文件的大小
if (dwCompression != BI_RGB)
bi.biSizeImage = (bi.biSizeImage * 3) / 2;
}
//重新分配内存以容纳所有内容
dwLen += bi.biSizeImage;
if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
hDIB = handle;
else
{
GlobalFree(hDIB);
// 重新选择逻辑调色板
SelectPalette(hDC,hPal,FALSE);
ReleaseDC(NULL,hDC);
return NULL;
}
// Get the bitmap bits
lpbi = (LPBITMAPINFOHEADER)hDIB;
// 最后得到DIB
BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
0L, // 开始扫描的行
(DWORD)bi.biHeight, // 扫描的总行数
(LPBYTE)lpbi // bitmap文件象素的地址
+ (bi.biSize + nColors * sizeof(RGBQUAD)),
(LPBITMAPINFO)lpbi, // bitmapinfo的地址
(DWORD)DIB_RGB_COLORS); // 使用RGB作为色彩表
if( !bGotBits )
{
GlobalFree(hDIB);
SelectPalette(hDC,hPal,FALSE);
ReleaseDC(NULL,hDC);
return NULL;
}
SelectPalette(hDC,hPal,FALSE);
SeleaseDC(NULL,hDC);
return hDIB;
}
}