使用DirectX截屏
網(wǎng)上有很多關(guān)于DirectX截屏的文章,但大都是屏幕截圖,很少有窗口截圖,本文則兩者都涉及到,先講如何截取整個(gè)屏幕,再講如何截取某個(gè)窗口,其實(shí)二者的區(qū)別不大,只是某個(gè)參數(shù)的設(shè)置不同而已,最后我們還將擴(kuò)展到任意區(qū)域的截圖。
首先看一下截屏用到的函數(shù),最核心的當(dāng)然是D3DXSaveSurfaceToFile,先看下函數(shù)原型
1?HRESULT?D3DXSaveSurfaceToFile(2???LPCTSTR?pDestFile,
3???D3DXIMAGE_FILEFORMAT?DestFormat,
4???LPDIRECT3DSURFACE9?pSrcSurface,
5???CONST?PALETTEENTRY?*?pSrcPalette,
6???CONST?RECT?*?pSrcRect
7?);
第一個(gè)參數(shù)是指向設(shè)備的指針,不多說(shuō)啦
第二個(gè)參數(shù)是截圖文件的類型,支持的類型還不少,主要有下面這些
BMP,JPG,TGA,PNG,DDS,PPM,DIB,HDR,PFM
這里我們使用BMP-即位圖格式
第三個(gè)參數(shù)是指向Surface的指針,也就是保存了截圖數(shù)據(jù)的表面
第四個(gè)參數(shù)是Surface的調(diào)色板,這里不使用,設(shè)置為NULL
最后一個(gè)參數(shù)是Surface的矩形區(qū)域,也就是我們可以只截取Surface上某一矩形區(qū)域的數(shù)據(jù),其實(shí)截取全屏和截取窗口的差別也就在這個(gè)參數(shù)的設(shè)置上
其他的函數(shù)在下面會(huì)逐一講解
現(xiàn)在來(lái)定義我們的截屏函數(shù),首先我們需要一個(gè)設(shè)備指針,因?yàn)樵贒X中,任何操作都與設(shè)備密切相關(guān),所以設(shè)備指針幾乎是每個(gè)DX函數(shù)都要用到的參數(shù),我們這個(gè)函數(shù)也不例外,其次需要一個(gè)窗口句柄,當(dāng)我們截取窗口時(shí),把窗口句柄傳入,當(dāng)我們截取整個(gè)屏幕時(shí),直接傳入NULL。最后我們需要一個(gè)字符串參數(shù)來(lái)指定截圖對(duì)應(yīng)的文件名,如下
1?BOOL?ScreenShot(LPDIRECT3DDEVICE9?lpDevice,?HWND?hWnd,?TCHAR*?fileName)詳細(xì)步驟:
首先我們需要獲取顯示模式,注意這里獲取的是顯卡的顯示模式,而不是設(shè)備的顯示模式,因?yàn)樵O(shè)備的顯示模式既有窗口模式,也有全屏模式,所以它的分辨率是不確定的,而顯卡的顯示模式返回的始終是最大分辨率,我們需要?jiǎng)?chuàng)建整個(gè)屏幕區(qū)域?qū)?yīng)的Surface,當(dāng)截取整個(gè)屏幕時(shí),直接保存即可,當(dāng)截取窗口時(shí),我們將窗口所對(duì)應(yīng)的區(qū)域保存即可
獲取顯卡顯示模式的代碼如下
1?HRESULT?hr;2?
3??//?Get?adapter?display?mode
4?D3DDISPLAYMODE?mode;
5?if?(FAILED(hr?=?lpDevice->GetDisplayMode(0,?&mode)))
6?????return?hr;
7?
下面開始創(chuàng)建表面,這個(gè)表面是對(duì)應(yīng)整個(gè)屏幕的
Code接下來(lái)獲取屏幕對(duì)應(yīng)的數(shù)據(jù),這個(gè)函數(shù)實(shí)際上是將顯存中的數(shù)據(jù)拷貝到系統(tǒng)內(nèi)存中
1?//?Get?the?screen?data2?if?(FAILED(hr?=?lpDevice->GetFrontBufferData(0,?surf)))
3?{
4?????surf->Release()?;
5?????return?hr?;
6?}
7?
接下來(lái)我們判斷是截取窗口還是截取屏幕,很簡(jiǎn)單,只需判斷hWnd是否為NULL即可,如果是截取窗口則設(shè)置窗口對(duì)應(yīng)的矩形區(qū)域即可
Code最后一步,保存截圖!
1?//?Save?the?screen?date?to?file2?hr?=?D3DXSaveSurfaceToFile(fileName,?D3DXIFF_BMP,?surf,?NULL,?rect);
3?
4?surf->Release()?;
5?
6?return?hr?;
7?
完整代碼
Code那么如何實(shí)現(xiàn)任意區(qū)域截屏呢,我想大家已經(jīng)想到了,假設(shè)使用鼠標(biāo)拖拽的方法截圖,記下鼠標(biāo)按下和抬起時(shí)的坐標(biāo),構(gòu)造一個(gè)RECT,然后傳遞給D3DXSaveSurfaceToFile函數(shù)就可以了,需要注意到是,由于鼠標(biāo)拖拽到方向是任意的,所以在構(gòu)造RECT的時(shí)候要注意right < left或者bottom < top 的情況,用下面的方法可以處理
Codehappy coding!
==THE END==
?
轉(zhuǎn)載自:http://www.cnblogs.com/graphics/archive/2009/11/25/1610914.html
轉(zhuǎn)載于:https://www.cnblogs.com/OrdinaryTravel/p/4326024.html
總結(jié)
以上是生活随笔為你收集整理的使用DirectX截屏的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: struts2处理.do后缀的请求
- 下一篇: Hibernate学习笔记--第一个Hi