在Windows中执行全屏抓取

时间:2010-05-14 05:16:32

标签: c++ winapi mingw screenshot overlay

我正在研究一个想法,包括完整捕获屏幕,包括窗口和应用程序,分析它,然后将项目重新绘制到屏幕上,作为叠加层。

我想学习图像处理技术,如果我可以直接访问Windows屏幕,我可以获得大量数据。我可以使用它来构建以前从未见过的自动化工具。稍后会详细介绍。

我在大多数情况下都有全屏捕捉功能。

HWND hwind = GetDesktopWindow();
HDC hdc = GetDC(hwind);

int resx = GetSystemMetrics(SM_CXSCREEN);
int resy = GetSystemMetrics(SM_CYSCREEN);
int BitsPerPixel = GetDeviceCaps(hdc,BITSPIXEL);
HDC hdc2 = CreateCompatibleDC(hdc);

BITMAPINFO info;
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biWidth = resx;
info.bmiHeader.biHeight = resy;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biBitCount  = BitsPerPixel;
info.bmiHeader.biCompression = BI_RGB;

void *data;
hbitmap = CreateDIBSection(hdc2,&info,DIB_RGB_COLORS,(void**)&data,0,0);
SelectObject(hdc2,hbitmap);

一旦完成,我可以反复调用:

BitBlt(hdc2,0,0,resx,resy,hdc,0,0,SRCCOPY);

清理代码(我不知道这是否正确):

DeleteObject(hbitmap);
ReleaseDC(hwind,hdc);
if (hdc2) {
    DeleteDC(hdc2);
}

每次调用BitBlt时,它都会抓取屏幕并将其保存在内存中,我可以通过data访问它。

性能有点令人满意。 BitBlt在1920x1200x32下以50毫秒(有时低至33毫秒)执行。

让我感到惊讶的是,当我将显示模式切换为16位,1920x1200x16时,无论是事先通过我的图形设置,还是使用ChangeDisplaySettings,我获得了大大改进的屏幕抓取时间,介于1ms和2ms之间,这不能通过比特深度减少两个因素来解释。与使用CreateDIBSection(6-7ms / f)设置时相比,使用CreateCompatibleBitmap(如上所述)在16位模式下可显着提高速度。

有人知道为什么降到16位导致这样的速度增加吗?我有希望以这样的速度抓住32位吗?如果不是颜色深度,但不强制更改屏幕缓冲模式和可怕的闪烁。

1 个答案:

答案 0 :(得分:2)

我解决了关于切换到16位彩色模式令人难以置信的加速的原始问题。事实证明它导致Aero主题被禁用,这占了大部分主题。随着Aero在32位的关闭,它的速度也快得多。

Link其他主题有一个很好的答案。