步骤: 初始化BITMAPINFOHEADER数据结构。 用位图信息决定位图的宽高与字节数。 最好使用BI_RGB压缩。 实现并选择逻辑调色板。 决定位图使用的字节数。首先为BITMAPINFOHEADER和颜色表分配内存,然后调 用GetDIBits()去计算位图字节数。 给最终的位图尺寸分配内存块,包括BITMAPINFOHEADER和颜色表与位图字节数。 最终再调用GetDIBits()得到位图的字节数。 // DDBToDIB - Creates a DIB from a DDB // bitmap - Device dependent bitmap // dwCompression Type of compression - see BITMAPINFOHEADER // pPal Logical palette HANDLE DDBToDIB( CBitmap& bitmap, DWORD dwCompression, CPalette* pPal ) ITMAP m; ITMAPINFOHEADER i; PBITMAPINFOHEADER pbi; WORD wLen; ANDLE DIB; ANDLE andle; DC DC; PALETTE hPal; SSERT( bitmap.GetSafeHandle() ); / The function has no arg for bitfields f( dwCompression == BI_BITFIELDS ) return NULL; / If a palette has not been supplied use defaul palette Pal = (HPALETTE) pPal->GetSafeHandle(); f (hPal==NULL) hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE); / Get bitmap information itmap.GetObject(sizeof(bm),(LPSTR)&bm); / Initialize the bitmapinfoheader i.biSize = sizeof(BITMAPINFOHEADER); i.biWidth = bm.bmWidth; i.biHeight = bm.bmHeight; i.biPlanes = 1; i.biBitCount = bm.bmPlanes * bm.bmBitsPixel; i.biCompression dwCompression; i.biSizeImage = 0; i.biXPelsPerMeter 0; i.biYPelsPerMeter 0; i.biClrUsed = 0; i.biClrImportant 0; / Compute the size of the infoheader and the color table nt nColors = (1 << bi.biBitCount); f( nColors > 256 ) nColors = 0; wLen = bi.biSize + nColors * sizeof(RGBQUAD); / We need a device context to get the DIB from DC = GetDC(NULL); Pal = SelectPalette(hDC,hPal,FALSE); ealizePalette(hDC); / Allocate enough memory to hold bitmapinfoheader and color table DIB = GlobalAlloc(GMEM_FIXED,dwLen); f (!hDIB){ SelectPalette(hDC,hPal,FALSE); ReleaseDC(NULL,hDC); return NULL; pbi = (LPBITMAPINFOHEADER)hDIB; lpbi = bi; / Call GetDIBits with a NULL lpBits param, so the device driver / will calculate the biSizeImage field etDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight, LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS); i = *lpbi; / If the driver did not fill in the biSizeImage field, then compute it / Each scan line of the image is aligned on a DWORD (32bit) boundary f (bi.biSizeImage == 0){ bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) * bi.biHeight; // If a compression scheme is used the result may infact be larger // Increase the size to account for this. if (dwCompression != BI_RGB) i.biSizeImage = (bi.biSizeImage * 3) / 2; / Realloc the buffer so that it can hold all the bits wLen += bi.biSizeImage; f (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE)) hDIB = handle; lse{ GlobalFree(hDIB); // Reselect the original palette SelectPalette(hDC,hPal,FALSE); ReleaseDC(NULL,hDC); return NULL; / Get the bitmap bits pbi = (LPBITMAPINFOHEADER)hDIB; / FINALLY get the DIB OOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, // Start scan line (DWORD)bi.biHeight, // # of scan lines (LPBYTE)lpbi / address for bitmap bits + (bi.biSize + nColors * sizeof(RGBQUAD)), (LPBITMAPINFO)lpbi, // address of bitmapinfo (DWORD)DIB_RGB_COLORS); // Use RGB for color table f( !bGotBits ) GlobalFree(hDIB); SelectPalette(hDC,hPal,FALSE); ReleaseDC(NULL,hDC); return NULL; electPalette(hDC,hPal,FALSE); eleaseDC(NULL,hDC); eturn hDIB;
下面是以前CSDN上的一段代码(不是我写的,一位高人留下的)
转换DDB到DIB
步骤:
初始化BITMAPINFOHEADER数据结构。 用位图信息决定位图的宽高与字节数。
最好使用BI_RGB压缩。
实现并选择逻辑调色板。
决定位图使用的字节数。首先为BITMAPINFOHEADER和颜色表分配内存,然后调
用GetDIBits()去计算位图字节数。
给最终的位图尺寸分配内存块,包括BITMAPINFOHEADER和颜色表与位图字节数。
最终再调用GetDIBits()得到位图的字节数。
// DDBToDIB
- Creates a DIB from a DDB
// bitmap
- Device dependent bitmap
// dwCompression
Type of compression - see BITMAPINFOHEADER
// pPal
Logical palette
HANDLE DDBToDIB( CBitmap& bitmap, DWORD dwCompression, CPalette* pPal )
ITMAP
m;
ITMAPINFOHEADER
i;
PBITMAPINFOHEADER
pbi;
WORD
wLen;
ANDLE
DIB;
ANDLE
andle;
DC
DC;
PALETTE
hPal;
SSERT( bitmap.GetSafeHandle() );
/ The function has no arg for bitfields
f( dwCompression == BI_BITFIELDS )
return NULL;
/ If a palette has not been supplied use defaul palette
Pal = (HPALETTE) pPal->GetSafeHandle();
f (hPal==NULL)
hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
/ Get bitmap information
itmap.GetObject(sizeof(bm),(LPSTR)&bm);
/ Initialize the bitmapinfoheader
i.biSize
= sizeof(BITMAPINFOHEADER);
i.biWidth
= bm.bmWidth;
i.biHeight
= bm.bmHeight;
i.biPlanes
= 1;
i.biBitCount
= bm.bmPlanes * bm.bmBitsPixel;
i.biCompression
dwCompression;
i.biSizeImage
= 0;
i.biXPelsPerMeter
0;
i.biYPelsPerMeter
0;
i.biClrUsed
= 0;
i.biClrImportant
0;
/ Compute the size of the infoheader and the color table
nt nColors = (1 << bi.biBitCount);
f( nColors > 256 )
nColors = 0;
wLen = bi.biSize + nColors * sizeof(RGBQUAD);
/ We need a device context to get the DIB from
DC = GetDC(NULL);
Pal = SelectPalette(hDC,hPal,FALSE);
ealizePalette(hDC);
/ Allocate enough memory to hold bitmapinfoheader and color table
DIB = GlobalAlloc(GMEM_FIXED,dwLen);
f (!hDIB){
SelectPalette(hDC,hPal,FALSE);
ReleaseDC(NULL,hDC);
return NULL;
pbi = (LPBITMAPINFOHEADER)hDIB;
lpbi = bi;
/ Call GetDIBits with a NULL lpBits param, so the device driver
/ will calculate the biSizeImage field
etDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
i = *lpbi;
/ If the driver did not fill in the biSizeImage field, then compute it
/ Each scan line of the image is aligned on a DWORD (32bit) boundary
f (bi.biSizeImage == 0){
bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
* bi.biHeight;
// If a compression scheme is used the result may infact be larger
// Increase the size to account for this.
if (dwCompression != BI_RGB)
i.biSizeImage = (bi.biSizeImage * 3) / 2;
/ Realloc the buffer so that it can hold all the bits
wLen += bi.biSizeImage;
f (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
hDIB = handle;
lse{
GlobalFree(hDIB);
// Reselect the original palette
SelectPalette(hDC,hPal,FALSE);
ReleaseDC(NULL,hDC);
return NULL;
/ Get the bitmap bits
pbi = (LPBITMAPINFOHEADER)hDIB;
/ FINALLY get the DIB
OOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
0L,
// Start scan line
(DWORD)bi.biHeight,
// # of scan lines
(LPBYTE)lpbi
/ address for bitmap bits
+ (bi.biSize + nColors * sizeof(RGBQUAD)),
(LPBITMAPINFO)lpbi,
// address of bitmapinfo
(DWORD)DIB_RGB_COLORS);
// Use RGB for color table
f( !bGotBits )
GlobalFree(hDIB);
SelectPalette(hDC,hPal,FALSE);
ReleaseDC(NULL,hDC);
return NULL;
electPalette(hDC,hPal,FALSE);
eleaseDC(NULL,hDC);
eturn hDIB;
=================
没错啊,我上面的代码就是将DDB转成DIB的啊
参数好像没有HDC之类的,是不是这样,先创建一个位图对象,再创建一个内存描述表,把位图对象选入内存描述表。
然后进行BITBLIT,再用这个函数将位图对象转换成DIB,是不是这样? 效率太低了吧!
听说wltg2001您也在做远控方面的,我也是,能否交流一下,我位图这方面学的不太好.