Search code examples
c++winapidibgetdibits

GetDiBits: different dimensions passed in BITMAPINFOHEADER


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-?


Solution

  • 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.