DirectX截圖黑屏的解決辦法
好久沒有更新博客了,今天開始繼續耕耘。
生活要繼續
工作要繼續
夢想也一定要繼續!
之前寫過一篇關于DirectX截屏的文章,其中有網友留言提到了截圖黑屏的問題,于是這些日子研究了一下,與大家一同分享。
為什么會黑屏?
一句話概括,黑屏是由于DDraw加速引起的!
先說一下DirectX的顯示原理,通常我們看到的屏幕上的數據,都是通過Primary Surface送至顯示器的,什么是Primary Surface呢?中文叫做主顯示表面,也就是說我們當前看到的屏幕上的圖像數據是從這個表面來的,除了主表面意外還有離屏表面,叫做OffScreenSuface。這種表面中的數據是不直接顯示在屏幕上的。常用的截屏函數也基本上是通過截取Primary Surface中的數據來實現的。現在多數的視頻播放軟件都是用DDraw寫的(現在DDraw已經融合到DirectX的Graphics本分,DDraw這個詞也已經成為歷史了。),而且使用了一種叫做Overlay的表面,我們常用的截屏函數都是截取普通的primary surface中的數據,無法截取Overlay surface中的數據,而微軟又沒有提供公共的API來獲取Overlay surface中的數據,所以,黑屏就不足為奇了。下面就是使用了Overlay技術的Windows Media Player截圖時的黑屏現象。
Overlay是純硬件支持的,DDraw并不會用軟件實現這種功能。這種Surface的特殊之處在于,它相當于蒙在屏幕上的一塊塑料板,也就是說,這個如果使用了這種Surface,那么它就位于所有surface的最前端。顯示設備在向屏幕顯示數據的時候,會先判斷該位置是否有Overlay,如果有,就顯示Overlay中像素,如果沒有,就使用Primary Surface中的像素。所以,當你打開一個播放器來播放視頻,截圖的時候就會發現播放器窗口是黑的。原因就是這塊區域正好對應著Overlay。當然是截取不到的。
關于Overlay surfaces的詳細介紹,可以看這里。
如何避免截圖時黑屏
大多數軟件除了DDraw的渲染模式之外,還提供了一種Software renderer模式,也就是軟件模式,這種模式在DDraw加速不可用的時候才會使用,所以一個避免截圖黑屏的辦法就是關閉DDraw加速,強迫軟件使用Software renderer模式,這樣,Overlay surface就不存在了,也就不會黑屏了。具體辦法如下
方法一: 使用軟件本身的設置來禁用Overlay技術,該方法只會影響該軟件本身,以常見的Windows Media Player為例,設置如下(將 使用覆蓋這個選項勾掉,這樣軟件就不會使用Overlay Surface了)
方法二: 使用DirectX控制面板來關閉DDraw加速,上面的方法相當于關閉分支開關,而這個方法則相當于把總閘給關閉了,系統中所有其他軟件也不能使用DDraw加速了。如果安裝了DirectX SDK,那么直接在運行欄里面輸入dxdiag即可打開DirectX控制面板,設置如下。
方法三:其實還有一種辦法,就是用程序占用Overlay surface,這種辦法太麻煩,一般人不會用,因為一般的獨立顯卡都支持Overlay Surface,而且支持的個數是有限的,所以,如果我們提前用程序占用了所有的Overlay Surface,那么其他程序就無法再使用了,也就不會導致截圖黑屏了。在使用這種方法前,應該首先查看自己的顯卡是否支持Overlay技術,以及支持多少個。如果安裝了DirectX SDK,可以依次展開:開始-程序-Microsoft DirectX SDK-DirectX Utilities-DirectX Caps Viewer,由下圖可知,我的顯卡支持一個Overlay Surface,我還沒玩過高級顯卡,沒見過支持多個Overlay的顯卡,哪位兄弟有好的顯卡,也發個圖讓小弟看看。
但是這種方法有一個弊端,就是如果軟件不支持Software Renderer模式,那么如果你先用程序占用了Overlay,再啟動播放軟件的時候,就會導致錯誤。
以上幾種辦法究其本質,實際上就是一種,都是禁止使用Overlay Surface。而且這些方法都有一個弊端,就是要求先入為主,也就是在軟件啟動前(或者確切的說,是視頻播放前)做好設置,然后再啟動軟件。如果視頻已經播放(Overlay已經被占用),那么這些方法將會統統失效。
除此之外,還可以使用現成的截圖軟件,很多軟件都可以處理黑屏的情況,比如HyperSnap 6就很不錯。
如何截取Overlay中的數據?
說來這不是一個簡單的問題,我在網上搜索了很久,也沒找到合適的辦法,據說使用Hook技術可能會辦到,但是我對hook不太熟悉,所以也沒嘗試,希望哪位朋友有興趣可以試試,關于這個話題,google討論組上有個帖子,介紹的比較詳細,感興趣的可以看看這里。
挑戰一下!
我這里有一個關于Overlay Surface的Demo(下載)。這個Demo來自DirectX 7的SDK,是一只飛動的小蚊子。由于版本較老,現在網上已經不太常見了。根據上面的研究可以斷定,能截取到這只小蚊子絕非易事,感興趣的朋友不妨試試!
References
Hardware Overlay http://www.fox-magic.com/sva_overlays.php
from:http://www.cnblogs.com/graphics/archive/2012/04/03/2117798.html
RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成