【问题标题】:Why does GetObject return an BITMAP with null bmBits?为什么 GetObject 返回带有空 bmBits 的 BITMAP?
【发布时间】:2012-10-01 16:31:37
【问题描述】:

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

【问题讨论】:

  • 你是不是想用这段代码截屏,只是副手?看起来像。如果是这样的话,PrintWindow 不是你所需要的。它所做的只是将 WM_PRINT 发送到目标窗口,并在其上转储 DC。无法保证 window 甚至会处理该消息,如果是,请执行您想要的操作。您几乎拥有所需的一切,但我相信您需要使用 BitBlt() 将位从屏幕 DC 拉到兼容的 DC,并准备好接收它们的新位图。

标签: c++ windows gdi


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    仅供参考。 从文件加载位图并想使用 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
    

    【讨论】:

    • 这是我见过的唯一提到这一点的答案。先生,你真棒!
    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2011-10-18
        • 1970-01-01
        • 2021-06-29
        • 2023-04-05
        • 1970-01-01
        • 2011-11-24
        • 2019-11-23
        • 2013-01-18
        • 2017-01-17
        相关资源
        最近更新 更多