上下文:我正在尝试使用另一个窗口的屏幕截图将其提供给OpenCV。我在网上发现了一些应该能够将BITMAP转换为OpenCV可以使用的代码。不幸的是我遇到了一些麻烦。
问题:为什么bmBits属性/成员始终为null? (我也试过用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;
}
对于DIB部分,bmBits
成员不为null。对于依赖于设备的位图(例如您正在创建的位图),未设置bmBits
,因为像素位于视频卡上,而不是位于主存储器中。
在您的示例中,如果要直接访问位,则需要将CreateCompatibleBitmap
更改为CreateDIBSection
。
仅供参考。从文件加载位图并想要使用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
来自MSDN上的GetObject文档。请注意第二段。
如果hgdiobj是通过调用CreateDIBSection创建的位图的句柄,并且指定的缓冲区足够大,则GetObject函数返回
DIBSECTION
结构。此外,BITMAP
中包含的DIBSECTION
结构的bmBits成员将包含指向位图位值的指针。如果hgdiobj是通过任何其他方式创建的位图的句柄,则GetObject仅返回位图的宽度,高度和颜色格式信息。您可以通过调用GetDIBits或GetBitmapBits函数来获取位图的位值。
您可以做的一件事是查看GetObject的返回值。如果为0你知道出了什么问题。调用参数有问题。