我从桌面创建了一个屏幕截图,并收到了一个带有像素数据的矢量,但在试图在屏幕上绘制像素数据时遇到了问题。
创建屏幕快照的代码
std::vector<RGBQUAD> recvScreenSnippet(int x, int y, int width, int height) {
std::vector<RGBQUAD> v_screen_data(width*height);
HDC screen_dc = GetDC(NULL);
HDC mem_dc = CreateCompatibleDC(NULL);
HBITMAP hBmp = CreateCompatibleBitmap(screen_dc, width, height);
auto oldBmp = SelectObject(mem_dc, hBmp);
// 32 bit & Upside Down headers
BITMAPINFO bmi{};
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biHeight = height;
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
// Receive pixel data from hdc
BitBlt(mem_dc, 0, 0, width, height, screen_dc, x, y, SRCCOPY);
GetDIBits(mem_dc, hBmp, 0, height, &v_screen_data[0], &bmi, DIB_RGB_COLORS);
// Cleanup
SelectObject(mem_dc, oldBmp);
DeleteObject(hBmp);
DeleteDC(mem_dc);
ReleaseDC(0, screen_dc);
return v_screen_data;
}
字符串
在屏幕上绘制像素数据的代码:
void setScreenSnippet(int x, int y, int width, int height, std::vector<RGBQUAD> &v_pixel_data) {
HDC screen_dc = GetDC(0);
HDC mem_dc = CreateCompatibleDC(0);
// 32 bit & Upside Down headers
BITMAPINFO bmi{};
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biHeight = height;
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
// Create bitmap
HBITMAP bitmap = CreateCompatibleBitmap(mem_dc,width,height);
// Store pixel data in bitmap
SetDIBits(mem_dc, bitmap, 0, height, &v_pixel_data[0], &bmi, DIB_RGB_COLORS);
// Select bitmap data into mem_dc
SelectObject(mem_dc, bitmap);
while (true)
{
BitBlt(screen_dc, x, y, width, height, mem_dc, 0, 0, SRCCOPY);
Sleep(1);
}
// Cleanup
SelectObject(mem_dc, bitmap);
DeleteObject(bitmap);
ReleaseDC(0, screen_dc);
}
型
我怎么称呼它
int main()
{
Sleep(5000);
std::vector<RGBQUAD> v_pixel_data = recvScreenSnippet(600,600,400,400);
setScreenSnippet(100, 600, 400, 400, v_pixel_data);
system("pause"), exit(1);
}
型
问题是,绘制的屏幕截图顶部是黑色的,这意味着有些东西不起作用。
This is what it looks like
我做错了什么?
1条答案
按热度按时间kyxcudwk1#
首先,我必须道歉,我只在裸机项目中使用过C++,在这些项目中没有使用标准库函数(
std::...
),所以我对这些函数的了解非常有限。但是,让我们看看下面的代码:
字符串
由于对
std::vector
数据类型了解不多,我无法告诉您“第2行”在做什么;可能vector
x 1 m3n1x的大小被改变,因此它具有至少21个元素。不过,我可以肯定地告诉你在“第3行和第4行”中发生了什么:
在第3行中,生成指向
vector
的元素[0]
的指针。在第4行中,对指针(而不是对
vector
)执行操作。这意味着编译器不知道此操作会访问example2
vector
中的元素。因此,编译器绝对不会重新调整此行中
vector
的大小。如果
vector
中example2
已经大于300个元素,“第4行”将写入example2[300]
;如果它小于301个元素,这行代码将写入RAM中的任何位置,并且可能会因为覆盖重要数据(如堆栈上的返回地址)而导致程序崩溃。因此,在访问
pExample[300]
之前,必须确保example2
已经大于300个元素。这跟你的问题有什么关系?
Windows API函数执行指针操作,而不是
vector
操作。这意味着:
GetDIBits()
的内部工作方式如下:型
因此,在调用
GetDIBits()
之前,必须确保向量v_pixel_data
的大小至少为width * height
个元素。问题是,绘制的截图顶部是黑色的,这意味着有什么东西不工作。
Windows首先存储底部像素,最后存储顶部像素。
也许,你的
vector
足够大,可以容纳图像的一部分,但不能容纳完整的图像。