Reputation: 1039
I have some questions regarding GetDiBits, based on my experience with this function. By mistake I have created a bitmap double the size I needed:
HBITMAP hBmpSection = CreateCompatibleBitmap(ScreenDC, 2 * radius, 2 * radius);
I did not notice because the next part of the code worked. I BitBlt a section of the screen on half of this bitmap:
bmpSmallInfo.bmiHeader.biHeight = (2*radius / 2);
bmpSmallInfo.bmiHeader.biWidth = (2*radius / 2);
BitBlt(hSectionDC, 0, 0, bmpSmallInfo.bmiHeader.biWidth, bmpSmallInfo.bmiHeader.biHeight, ScreenDC, 0, 0, SRCCOPY);
Then I get the coresponding array:
GetDIBits(hSectionDC, hBmpSection, 0, bmpSmallInfo.bmiHeader.biHeight, dataBuffer3, &bmpSmallInfo, DIB_RGB_COLORS);
When I sent all this data to another computer , the image came perfectly right(no black edges around as it would have been in the case an oversized bitmap had been sent). This means that GetDiBits ignores the right size of the bitmap and uses the one provided in the BITMAPINFOHEADER,without crashing. (I'm using Win10.)
Is this normal? As I don't want to send unwanted bytes over network , I have to ask: does GetDiBits output an array the size of the right dimensions : (4*radius^2)*3 or does it look after the values from the structure : radius^2 *3 -ignoring padding-?
Upvotes: 3
Views: 549
Reputation: 36141
GetDIBits is a rather strange function by GDI standards. Instead of the usual pattern of taking either just an HDC
or an HBITMAP
it wants both, AND imposes additional restrictions on the HBITMAP
parameter. iirc This pattern is used when you are asking GDI to (potentially) transform a bitmap relative to a color table - i.e. in 8bit or lower images you should have a selected HPALETTE
in the HDC
.
The GetDIBits function page on MSDN however is quite clear - the LPBITMAPINFO
parameter is:
A pointer to a BITMAPINFO structure that specifies the desired format for the DIB data.
Subsequent comments clarify that, if lpvBits
is NULL, you can use GetDIBits to retrieve bitmap properties by writing them into the BITMAPINFO
structure.
To answer your specific question; GetDIBits
outputs to the dataBuffer using the dimensions and format you provide in the BITMAPINFOHEADER
and will clip & transform as necessary if the DDB
has different dimensions or pixel format.
Upvotes: 1
Reputation: 31669
Basically you have a code like this:
hbitmap = CreateCompatibleBitmap(hdc, max_width, max_height);
oldbmp = (HBITMAP)SelectObject(memdc, hbitmap);
BitBlt(memdc, 0, 0, width, height, hdc, x, y, SRCCOPY);
SelectObject(memdc, oldbmp);
int size = width_in_bytes_with_padding * height;
allocate size count memory ...
BITMAPINFOHEADER bi = { 40, width, height, 1, 24, BI_RGB };
GetDIBits(...);
The question you appear to be asking: Is it okay if width/height
is smaller than max_width/max_height
?
The answer is yes. GetDIBits
expects dataBuffer3
to be large enough to receive size
bytes. width/height
should be less than or equal to max_width/max_height
Note that BitBlt
is the slowest function in this code, that's what you need to optimize. CreateCompatibleBitmap
takes a few micro seconds, you won't save much by creating a larger bitmap.
Upvotes: 1