Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does GetObject return an BITMAP with null bmBits?

Tags:

c++

windows

gdi

Context: I'm trying to take a screenshot of another window to feed it into OpenCV. I found some code on the web that should be able to convert a BITMAP to something OpenCV can work with. Unfortunately I ran into some trouble.

Question: Why is the bmBits attribute/member always null? (I also tried with PrintWindow instead of BitBlt the result was the same)

#include <iostream>
#include <string>
#include <Windows.h>

int main(int argc, char* argv[])
{
    std::wstring windowName = L"Calculator";

    RECT rect;
    HWND hwnd = FindWindow(NULL, windowName.c_str());
    if (hwnd == NULL)
    {
        return 0;
    }
    GetClientRect(hwnd, &rect);

    HDC hdcScreen = GetDC(NULL);
    HDC hdc = CreateCompatibleDC(hdcScreen);
    HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen, 
        rect.right - rect.left, rect.bottom - rect.top);
    SelectObject(hdc, hbmp);

    PrintWindow(hwnd, hdc, PW_CLIENTONLY);

    BITMAP bmp;
    GetObject(hbmp, sizeof(BITMAP), &bmp);

    return 0;
}
like image 473
Borgleader Avatar asked Oct 11 '12 04:10

Borgleader


3 Answers

The bmBits member is non-null for DIB sections. For device-dependent bitmaps (such as the one you're creating), the bmBits is not set because the pixels are on the video card, not in main memory.

In your example, you need to change CreateCompatibleBitmap to CreateDIBSection if you want direct access to the bits.

like image 81
Raymond Chen Avatar answered Oct 04 '22 07:10

Raymond Chen


From GetObject documentation on MSDN. Please note the second paragraph.

If hgdiobj is a handle to a bitmap created by calling CreateDIBSection, and the specified buffer is large enough, the GetObject function returns a DIBSECTION structure. In addition, the bmBits member of the BITMAP structure contained within the DIBSECTION 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 the GetDIBits or GetBitmapBits function.

like image 32
Glenn Slayden Avatar answered Oct 04 '22 07:10

Glenn Slayden


Just for information. When loading bitmap from file and want to use BITMAP .bmBits (for glTexImage2D, glDrawPixels):

LoadImage(NULL, "path_to.bmp", IMAGE_BITMAP, 0, 0,
                                       LR_LOADFROMFILE);

u must specify flag LR_CREATEDIBSECTION

HBITMAP hBmp = NULL;
BITMAP BMp;
hBmp = (HBITMAP) LoadImage(NULL, "bitmap.bmp", IMAGE_BITMAP, 0, 0,
                                       LR_LOADFROMFILE | LR_CREATEDIBSECTION);
GetObject(hBmp, sizeof(BMp), &BMp);
//BMp.bmBits now points to data
like image 25
befzz Avatar answered Oct 04 '22 09:10

befzz