Windows桌面共享中一些常见的抓屏技术
1. BitBlt
我想做Windows开发应该都知道这个API, 它能实现DC间的内容拷贝, 如果我们把源DC指定成Monitor DC或是桌面DC, 它就能实现抓屏成果。
对付通过这种方法的抓屏, 有2点需要出格提醒:
a. 在XP下我们可以通过最后的拷贝标识表记标帜来控制是否拷贝layered window, 只有SRCCPY暗示拷贝内容不包罗layered window, 如果是SRCCPY | CAPTUREBLT暗示拷贝包孕Layered window在内的所有窗口。 这个标识表记标帜在Vista之后的系统(win7/win8),开启DWM的情况下, 已经掉效, 因为这种情况下所有的窗口都是layered window. b. 这种方法的抓屏在 Vista之后, 开启DWM的情况下, 抓屏速度非常慢(30ms +), 具体原因不知道是因为系统没有缓存整个屏幕的数据还是GPU向内存拷贝数据太慢了, 有知道的伴侣可以提示下。
2. Mirror driver
这种要领应该是Win8之前最高效的抓屏要领, 也是微软保举的长途桌面共享方案,它通过创建虚拟镜像驱动, 直接获取最终屏幕变革数据。
该要领也有一些错误谬误:
a. 涉及到驱动安置, 技术难度大, 系统权限要求也高
b. Win8 上该方案已经掉效, 但是还是有要领的, 参见 Remote Display Drivers
3. GDI hook
这种要领应该说是XP时代对照风行的抓屏要领, 因为所有的绘制都是通过GDI32.dll中的绘图函数来实现的, 所以我们只要拦截了这些函数, 系统的所有绘制就都让我们控制了。这种要领应该来说也是一种挺高效的抓屏要领,屏幕的变革也都能让我们拦截到, 同时因为好多绘图函数是以矢量方法实现的,所有抓到的数据包非常小, 即使在低带宽下也效果挺好。
下面是该要领的一些错误谬误:
a. Hook技术自己就有其庞大性和不不变性, 尤其是Hook所有进程
b. Vista只有越来越多措施给与D2D/D3D绘制, GDI Hook对这些绘制无能为力。
c. Vista之后UAC打开的情况下, 如果我们的措施权限不够高, Hook不到更高权限的措施。
4. Windows Media API
Windows Media 9.0 撑持用Windows Media Encoder 9 API来抓屏。它有一个编码器叫Windows Media Video 9 Screen codec,出格为抓屏优化过。Windows Media Encoder API供给了一个IWMEncoder2接口可以用来高效地捕捉屏幕图像。
因为对这组API不熟, 这种抓屏要领我也没测验考试过, 具体可见, 觉得这种要领的最大错误谬误是用户机器需要安置Windows Media Encoder 9。
5. DirectX
每个DirectX措施都包罗一个被我们称作缓冲的内存区域,此中生存了和该措施有关的显存内容,这在措施中被称作后台缓冲(Back Buffer),有些措施有不止一个的后台缓冲。还有一个缓冲,在默认情况下每个措施都可以访谒-前台缓冲。前台缓冲生存了和桌面相关的显存内容,本色上就是屏幕图像。 我们的措施通过访谒前台缓冲就可以捕捉到当前屏幕的内容。上面的列子中也包罗该要领的实现, 是基于DirectX9的,我们可以参考下, 据我测试该要领在DWM打开的情况下抓整屏也要30ms摆布。Vista之后的DirectX 10/11相对付DirectX 9 已经产生非常大的变革, 直接用新的接口上面的代码未必能正常事情。
6. PrintWindow
该要领自己不能直接做为一种抓屏要领, 但是有时候我们要获取某个窗口的内容,, 即使他被其他窗口笼罩着, 这时候这个函数就很有用。该方该挪用法的道理是通过给方针窗口发送WM_PRINT或是WM_PRINTCLIENT动静, 所以如果方针窗口没有响应, 该挪用可能会梗阻抓屏线程, 这种情况下抓屏前最好先用SendMessageTimeout检测方针窗口是否有响应。此外该要领也抓不到D3D窗口的内容。
7. DWM/Dxgi hook
Vista之后微软放弃了XP时代的XPDM, 给与了全新的WDDM视屏驱动模型, 此刻Win8.1上已经是WDDM1.3.
Vista之后底层所有的衬着都是基于D3D技术, 此外我们也知道系统在DWM.exe里进行窗口边框的绘画和合成, 所以理论上我们可以通过HOOK DWM/D3D/DXGI,拦截到整个系统的屏幕内容。固然作为一种Hook技术, 它也有上面GDI Hook类似的问题。
8. Magnification
这组API是微软Vista之后开放给我们开发放大镜措施的, 它里面供给了一个API让我们拦截到显示的内容, 可惜的是这个关键的API MagSetImageScalingCallback 微软已经公布颁爆发废。此外该方法的抓屏效率也不高, 整屏需要60 ms 摆布。
9. Desktop Duplication