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
hgdiobj
is a handle to a bitmap created by callingCreateDIBSection
, and the specified buffer is large enough, theGetObject
function returns aDIBSECTION
structure. In addition, thebmBits
member of theBITMAP
structure contained within theDIBSECTION
will contain a pointer to the bitmap's bit values.If
hgdiobj
is a handle to a bitmap created by any other means,GetObject
returns only the width, height, and color format information of the bitmap. You can obtain the bitmap's bit values by calling theGetDIBits
orGetBitmapBits
function.
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
CreateDIBSection
bitmap.bmBit
pointer 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?