大家好我有以下代码:
#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)]);
}
答案 0 :(得分:3)
你有一个,也许是两个问题。
首先,您将参数作为指针的地址传递,即BYTE **
。但是,您只将它用作单个指针。这意味着当您致电GetDIBits
时,它会填写错误的地址。您应该已经由编译器发出警告。
第二个问题更具潜力,因为可能存在您未显示的代码,但是您永远不会初始化screenData
指针。您似乎没有分配内存来将位图数据复制到。
上述两个问题都会导致未定义的行为,这些行为有时似乎有效但不正确,或者可能随时崩溃。
至于指针问题,指针正是它的名字所说的:它指向某个东西。对于screenData
指针,可以将其显示为:
+------------+ +---------------------------------+ | screenData | ---> | Memory allocated for screenData | +------------+ +---------------------------------+
但是,当您在&
的调用中使用地址操作符captureScreenshot
时,您将创建一个指向screenData
变量的新指针:
+-------------+ +------------+ +---------------------------------+ | &screenData | ---> | screenData | ---> | Memory allocated for screenData | +-------------+ +------------+ +---------------------------------+
从上面的简单“图片”中,很容易看出为什么使用&screenData
不起作用,它只是指向一个完全不同的内存位置。
答案 1 :(得分:0)
正如@Joachim Pileborg指出的那样,screenData
必须预先分配一个适当大小的缓冲区。如果screenData
为空,GetDIBits()
仅填充BITMAPINFO结构(请参阅here)。如果screenData
未分配,则可能指向内存的随机部分,这通常会导致崩溃。
无论哪种方式,代码都应检查GetDIBits()
的返回值,以了解发生了什么。