|
发表于 2012-4-26 14:21:36
|
显示全部楼层
本帖最后由 happytc 于 2012-4-26 14:38 编辑
回复 3# kenan
因为_ScreenCapture_Capture函数是通过截取主表面(Primary Surface)中的数据来实现的。而视频或游戏基本上是用叫做覆盖表面(Overlay Surface)的数据,我们常用的截屏函数都是截取普通的primary surface中的数据,无法截取Overlay surface中的数据,而该死的微软又没有提供公共的API来获取Overlay surface中的数据,所以,黑屏就不足为奇了。Overlay是纯硬件支持的,而不OS的。显示设备在向屏幕显示数据的时候,会先判断该位置是否有Overlay,如果有,就显示Overlay中像素,如果没有,就使用Primary Surface中的像素。
简单的方法实现这种截图,就是关掉所谓的硬件加速:
①现在一般的软件本身可以设置来禁用Overlay技术,如Windows media player软件,就可以去掉‘使用覆盖’的勾;或叫开启软件显示模式(software rendering)
②在Windows上整个禁用Overlay,在DirectX控制面板上的‘显示’中禁用DirectDraw加速
若想不禁用Overlay情况下截图,就比较复杂了,一般你需要读取显卡缓冲中的overlay surface数据,再截取屏幕位图数据,然后你再把overlay得到数据转成图像后放在屏幕位图上面,也就是用bitBlt来合并它们
也就需要如下的步骤来做这种截图:
(1)获取显卡显示模式
(2)创建Plain Surface表面
(3)读取显存中的数据
(4)保存截图(这一步,微软倒是提供了D3DXSaveSurfaceToFile函数,这样就不用像用Bitblt那样,你得精确地把Overlay图像放准位置,不过得装Directx的SDK才能用)
========= 号外 ========
另外_ScreenCapture_Capture函数也不能截layered window窗口,也就是GUI加了$WS_EX_LAYERED样式的。这个不知道算不算Bug了,你可以在这个函数定义中的下面一行
_WinAPI_BitBlt($hCDC, 0, 0, $iW, $iH, $hDDC, $iLeft, $iTop, $__SCREENCAPTURECONSTANT_SRCCOPY)
替换成:
_WinAPI_BitBlt($hCDC, 0, 0, $iW, $iH, $hDDC, $iLeft, $iTop, BitOR($SRCCOPY, $CAPTUREBLT)) |
评分
-
查看全部评分
|