Performing full screen grab in windows
Posted
by Steven Lu
on Stack Overflow
See other posts from Stack Overflow
or by Steven Lu
Published on 2010-05-14T05:16:31Z
Indexed on
2010/05/14
5:24 UTC
Read the original article
Hit count: 285
I am working an idea that involves getting a full capture of the screen including windows and apps, analyzing it, and then drawing items back onto the screen, as an overlay.
I want to learn image processing techniques and I could get lots of data to work with if I can directly access the Windows screen. I could use this to build automation tools the likes of which have never been seen before. More on that later.
I have full screen capture working for the most part.
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);
Once this is done, I can call this repeatedly:
BitBlt(hdc2,0,0,resx,resy,hdc,0,0,SRCCOPY);
The cleanup code (I have no idea if this is correct):
DeleteObject(hbitmap);
ReleaseDC(hwind,hdc);
if (hdc2) {
DeleteDC(hdc2);
}
Every time BitBlt is called it grabs the screen and saves it in memory I can access thru data
.
Performance is somewhat satisfactory. BitBlt executes in 50 milliseconds (sometimes as low as 33ms) at 1920x1200x32.
What surprises me is that when I switch display mode to 16 bit, 1920x1200x16, either through my graphics settings beforehand, or by using ChangeDisplaySettings
, I get a massively improved screen grab time between 1ms and 2ms, which cannot be explained by the factor of two reduction in bit-depth. Using CreateDIBSection
(as above) offers a significant speed up when in 16-bit mode, compared to if I set up with CreateCompatibleBitmap
(6-7ms/f).
Does anybody know why dropping to 16bit causes such a speed increase? Is there any hope for me to grab 32bit at such speeds? if not for the color depth, but for not forcing a change of screen buffer modes and the awful flickering.
© Stack Overflow or respective owner