【问题标题】:Having issues with byte array/capturing a screenshot字节数组/捕获屏幕截图有问题
【发布时间】:2013-03-31 00:20:04
【问题描述】:

大家好,我有以下代码:

#define ScreenXResolution GetDeviceCaps(GetDC(0), HORZRES)
#define ScreenYResolution GetDeviceCaps(GetDC(0), VERTRES)

BYTE *screenData = malloc(sizeof(BYTE) * (3 * ScreenXResolution * ScreenYResolution));
captureScreenshot(&screenData);

void captureScreenshot(BYTE *screenData)
{
    HDC hdc = GetDC(NULL), hdcMem = CreateCompatibleDC(hdc);
    HBITMAP hBitmap = CreateCompatibleBitmap(hdc, ScreenXResolution, ScreenYResolution);
    BITMAPINFOHEADER bmi = {0};
    bmi.biSize = sizeof(BITMAPINFOHEADER);
    bmi.biPlanes = 1;
    bmi.biBitCount = 24;
    bmi.biWidth = ScreenXResolution;
    bmi.biHeight = -ScreenYResolution;
    bmi.biCompression = BI_RGB;
    SelectObject(hdcMem, hBitmap);
    BitBlt(hdcMem, 0, 0, ScreenXResolution, ScreenYResolution, hdc, 0, 0, SRCCOPY);
    GetDIBits(hdc, hBitmap, 0, ScreenYResolution, screenData, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
    DeleteObject(hBitmap);
    DeleteDC(hdcMem);
    ReleaseDC(NULL, hdc);
}

我想要实现的是截取他们的屏幕截图并将其放入 screenData。

我需要它的原因是我可以在任何位置检查它是否是某种 RGB 颜色,但我在这样做时遇到了问题。

如果有人可以帮助我,将不胜感激。

谢谢!

编辑:添加了内存分配,我尝试获取 RGB 的方式是通过一个返回 colorref 的函数,如下所示:

COLORREF getRGBFromScreenshot(BYTE *screenshot, int x, int y)
{
    return RGB(screenshot[3 * ((y * ScreenXResolution) + x) + 2], screenshot[3 * ((y * ScreenXResolution) + x) + 1], screenshot[3 * ((y * ScreenXResolution) + x)]);
}

【问题讨论】:

  • 这里有问题吗?你有什么“问题”?

标签: c winapi


【解决方案1】:

你有一个,也许是两个问题。

第一个是将参数作为指针的地址传递,即BYTE **。但是,您只能将其用作单个指针。这意味着当您拨打GetDIBits 时,它会填写错误的地址。你应该已经得到了编译器的警告。

第二个问题更有可能,因为可能有代码你没有显示,但你从来没有初始化screenData 指针。您似乎没有分配内存来将位图数据复制到其中。

以上两个问题都会导致未定义的行为,这可能有时似乎工作但不正确,或者随时可能崩溃。


至于指针问题,指针正是它的名字所说的:它指向某物。对于您的 screenData 指针,可以将其可视化如下:

+------------+ +---------------------------------+ |屏幕数据 | ---> |为 screenData | 分配的内存 +------------+ +---------------------------------+

但是,当您在对captureScreenshot 的调用中使用地址运算符& 时,您正在创建一个指向screenData 变量的新指针:

+-------------+ +------------+ +-------- -------------+ | &screenData | ---> |屏幕数据 | ---> |为 screenData | 分配的内存 +-------------+ +------------+ +-------- -------------+

从上面简单的“图片”中,很容易看出为什么使用&screenData 不起作用,它只是指向一个完全不同的内存位置。

【讨论】:

  • 用内存分配编辑了我的帖子,抱歉,我不明白指针问题:X 指针仍然让我感到困惑,抱歉。
  • 好吧,显然我修好了,我尝试了很多东西,明白我做错了什么谢谢!
  • @user2204015 用指针问题的解释更新了我的答案。
  • 谢谢,我很感激,当你在做的时候,如果我在我的 captureScreenshot 函数中没有做正确的事情,你能否告诉我,如果我循环该函数,我的程序似乎需要更多即使在循环停止后内存也不会下降,还有更多资源,有什么我没有释放/释放/删除的东西吗?
【解决方案2】:

正如@Joachim Pileborg 所说,screenData 必须预先分配一个适当大小的缓冲区。如果screenData 为空,GetDIBits() 仅填充 BITMAPINFO 结构(请参阅here)。如果screenData 未分配,它可能指向内存的随机部分,这通常会导致崩溃。

无论哪种方式,代码都应该检查来自GetDIBits() 的返回值,以了解发生了什么。

【讨论】:

  • 用screenData的内存分配编辑帖子
  • 你能检查GetDIBits()返回的值吗?如果函数失败它应该是0,否则它应该是从位图复制的扫描线数。
  • 刚刚检查并返回 0 :X
  • 感谢您的帮助我尝试了很多东西并找到了答案!谢谢
  • @user2204015:为了帮助将来遇到与您相同困难的其他人,您能否发布您的解决方案作为您自己问题的答案?谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
  • 2012-01-20
  • 1970-01-01
  • 2017-12-03
  • 2023-03-29
相关资源
最近更新 更多