11

上下文:我正在尝试截取另一个窗口的屏幕截图以将其输入 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

4 回答 4

18

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

在您的示例中,您需要更改CreateCompatibleBitmapCreateDIBSection是否要直接访问这些位。

于 2012-10-11T04:49:58.600 回答
10

仅供参考。从文件加载位图并希望使用 BITMAP .bmBits(对于glTexImage2DglDrawPixels):

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
于 2014-08-10T16:28:19.083 回答
4

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

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

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

于 2017-12-19T01:21:22.080 回答
-2

您可以做的一件事是查看 GetObject 的返回值。如果为 0,您就知道出了问题。调用的参数有问题。

于 2014-12-15T09:03:30.460 回答