windows系统中,抓取屏幕有很多方法,比较常用的是GDI和mirror两种方式,除此以外,利用ddraw和DXGI(windows7以上系统支持)方式也可以抓取屏幕。由于mirror的方式涉及到驱动底层,并且也不是所有系统都支持,这里不做介绍,着重介绍GDI, DDRAW和DXGI这三种抓屏方式,
所有的windows版本都通用的抓屏方式,这种抓屏方式相对比较慢,抓取一帧1080p的桌面需要5~8ms左右的时间。而且在vista以后的系统上,如果启用Aero特效的话,效率较低。
缺点:效率较差。
HDC window_dc = ::GetDC(::GetDesktopWindow()); winWidth_ = GetDeviceCaps(window_dc, HORZRES); winHeight_ = GetDeviceCaps(window_dc, VERTRES); hTemp_ = CreateCompatibleDC(window_dc); memBitmap_ = CreateCompatibleBitmap(window_dc, winWidth_, winHeight_); oldmemBitmap_ = (HBITMAP)SelectObject(hTemp_, memBitmap_); int rgbSize = 4 * winWidth_ * winHeight_; bih_.biBitCount = 32; bih_.biCompression = BI_RGB; bih_.biHeight = -winHeight_; bih_.biPlanes = 1; bih_.biSize = sizeof(BITMAPINFOHEADER); bih_.biSizeImage = rgbSize; bih_.biWidth = winWidth_; BitBlt(hTemp_, 0, 0, winWidth_, winHeight_, window_dc, 0, 0, SRCCOPY | CAPTUREBLT); GetDIBits(hTemp_, memBitmap_, 0, winHeight_, rgbPtr_, (LPBITMAPINFO)&bih_, DIB_RGB_COLORS ); DeleteDC(hTemp_); ::ReleaseDC(::GetDesktopWindow(), window_dc); DeleteObject(memBitmap_);
这种抓屏方式,速度非常快,而且即使启用了Aero特效,抓屏效率也一样。尤其在windows10以后的系统上,当桌面没有变化时,你是抓取不到任何图像的,只有在桌面有变化时,你才能抓取到图像。这会带来更高的抓屏效率和更少的系统开销。当然,它也不是完美的,它只能在vista以上的系统上才可以使用,老旧的xp是不支持这种新技术的。
缺点:但是只适用于win8及以后的操作系统,win7以前的系统无法使用此接口,不支持抓局部屏,只能是全屏。只能使用vs2012以上的IDE才可以编译。