Windows抓屏技術

來源:互聯網
上載者:User

標籤:print   enc   任務   系統   相關   setimage   進程   記憶體   方法   

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不熟, 這種抓屏方法我也沒嘗試過, 具體可見Various methods for capturing the screen, 感覺這種方法的最大缺點是使用者機器需要安裝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    這是微軟Win8 上宣布放棄Mirror driver之後推薦採用的抓屏技術, 全部基於D3D/DXGI技術, 效率非常高, 並且包含變化地區和螢幕滑鼠游標。它的缺點是沒法抓取某個視窗的內容 。


10. GetWindowDC 
該方法和PrintWindow類似,但是它沒有PrintWindow的許可權問題, 也沒有逾時問題。
這種抓屏方法在Win7/Win8  DWM開啟的情況下抓屏,結果會顛覆我們XP時代的知識, 因為即使視窗被覆蓋, 它也可以正確抓取到被覆蓋視窗下的內容, WebRTC正是用這種方式來Share  Application的。
它的主要問題是有些視窗抓到的內容不包含非客戶區,有些視窗比如工作列的Thumbnail視窗會抓不到內容。 http://www.cppblog.com/weiym/archive/2013/12/01/204536.html

Windows抓屏技術

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.