为什么GetObject返回带有bmBits的BITMAP?

时间:2012-10-11 04:36:48

标签: c++ windows gdi

上下文:我正在尝试截取另一个窗口的屏幕截图,将其提供给OpenCV。我在网上发现了一些应该能够将BITMAP转换为OpenCV可以使用的代码。不幸的是我遇到了一些麻烦。

问题:为什么bmBits属性/成员总是为空? (我也试过PrintWindow而不是BitBlt,结果是一样的)

#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;
}

4 个答案:

答案 0 :(得分:17)

对于DIB部分,bmBits成员非空。对于与设备相关的位图(例如您正在创建的位图),bmBits未设置,因为像素在视频卡上,而不在主存储器中。

在您的示例中,如果您想直接访问这些位,则需要将CreateCompatibleBitmap更改为CreateDIBSection

答案 1 :(得分:9)

仅供参考。 从文件加载位图并想要使用BITMAP .bmBits (对于 glTexImage2D glDrawPixels )时:

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

你必须指定标志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

答案 2 :(得分:3)

来自MSDN上的 GetObject 文档。请注意第二段。

  

如果 hgdiobj 是通过调用 CreateDIBSection 创建的位图的句柄,并且指定的缓冲区足够大,则 GetObject 函数返回DIBSECTION结构。此外,BITMAP中包含的DIBSECTION结构的 bmBits 成员将包含指向位图的位值的指针。

     

如果 hgdiobj 是通过任何其他方式创建的位图的句柄, GetObject 仅返回位图的宽度,高度和颜色格式信息。您可以通过调用 GetDIBits GetBitmapBits 函数来获取位图的位值。

答案 3 :(得分:-2)

您可以做的一件事是查看GetObject的返回值。如果为0你知道出了什么问题。呼叫参数有问题。