I have an HBITMAP handle to a device-dependent bitmap, resulting from this code:
// copy screen to bitmap
HDC hScreen = GetDC(NULL);//don't use hwnd, it doesn't work for non native windows
HDC hDC = CreateCompatibleDC(hScreen);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, w, h);
HGDIOBJ old_obj = SelectObject(hDC, hBitmap);
BOOL bRet = BitBlt(hDC, 0, 0, w, h, hScreen, x1, y1, SRCCOPY);
I want to access (read-only) the bits of the bitmap, read some values, do some calculations, then discard it.
According to this answer, I shouldn't use GetDIBits() or GetBitmapBits() since they copy the data, but instead I should use:
BITMAP bitmap;
GetObject(hBitmap, sizeof(bitmap), (LPVOID)&bitmap);
But according to GetObject's documentation:
If
hgdiobjis a handle to a bitmap created by callingCreateDIBSection, and the specified buffer is large enough, theGetObjectfunction returns aDIBSECTIONstructure. In addition, thebmBitsmember of theBITMAPstructure contained within theDIBSECTIONwill contain a pointer to the bitmap's bit values.If
hgdiobjis a handle to a bitmap created by any other means,GetObjectreturns only the width, height, and color format information of the bitmap. You can obtain the bitmap's bit values by calling theGetDIBitsorGetBitmapBitsfunction.
Which is pointed to in a comment on the above answer:
According to this https://msdn.microsoft.com/en-us/library/dd144904(v=vs.85).aspx if bitmap is not created by
CreateDIBSectionbitmap.bmBitpointer will be null.
So, is there anyway to access the bits of the bitmap (RGB values), without copying them?
If it helps, the device on which the bitmap is dependent is always a screen, so I guess it's always a 24bit or 32bit bitmap.
In this article, regarding how to save an HBITMAP to a file, there's this section:
// Allocate memory for the BITMAPINFO structure. (This structure
// contains a BITMAPINFOHEADER structure and an array of RGBQUAD
// data structures.)
if (cClrBits < 24) pbmi = (PBITMAPINFO)LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1 << cClrBits));
// There is no RGBQUAD array for these formats: 24-bit-per-pixel or 32-bit-per-pixel
else pbmi = (PBITMAPINFO)LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER));
So, I don't really understand what's happening here, and which is right?