使用DirectX截屏

简介:

如果截图变黑,请参考这一篇,DirectX截图黑屏的解决办法

网上有很多关于DirectX截屏的文章,但大都是屏幕截图,很少有窗口截图,本文则两者都涉及到,先讲如何截取整个屏幕,再讲如何截取某个窗口,其实二者的区别不大,只是某个参数的设置不同而已,最后我们还将扩展到任意区域的截图。

首先看一下截屏用到的函数,最核心的当然是D3DXSaveSurfaceToFile,先看下函数原型

复制代码
1  HRESULT D3DXSaveSurfaceToFile(
2    LPCTSTR pDestFile,
3    D3DXIMAGE_FILEFORMAT DestFormat,
4    LPDIRECT3DSURFACE9 pSrcSurface,
5    CONST PALETTEENTRY  *  pSrcPalette,
6    CONST RECT  *  pSrcRect
7  );
复制代码

第一个参数是指向设备的指针,不多说啦

第二个参数是截图文件的类型,支持的类型还不少,主要有下面这些

BMP,JPG,TGA,PNG,DDS,PPM,DIB,HDR,PFM

这里我们使用BMP-即位图格式

第三个参数是指向Surface的指针,也就是保存了截图数据的表面

第四个参数是Surface的调色板,这里不使用,设置为NULL

最后一个参数是Surface的矩形区域,也就是我们可以只截取Surface上某一矩形区域的数据,其实截取全屏和截取窗口的差别也就在这个参数的设置上

其他的函数在下面会逐一讲解

现在来定义我们的截屏函数,首先我们需要一个设备指针,因为在DX中,任何操作都与设备密切相关,所以设备指针几乎是每个DX函数都要用到的参数,我们这个函数也不例外,其次需要一个窗口句柄,当我们截取窗口时,把窗口句柄传入,当我们截取整个屏幕时,直接传入NULL。最后我们需要一个字符串参数来指定截图对应的文件名,如下

1  BOOL ScreenShot(LPDIRECT3DDEVICE9 lpDevice, HWND hWnd, TCHAR *  fileName)

详细步骤:

首先我们需要获取显示模式,注意这里获取的是显卡的显示模式,而不是设备的显示模式,因为设备的显示模式既有窗口模式,也有全屏模式,所以它的分辨率是不确定的,而显卡的显示模式返回的始终是最大分辨率,我们需要创建整个屏幕区域对应的Surface,当截取整个屏幕时,直接保存即可,当截取窗口时,我们将窗口所对应的区域保存即可

获取显卡显示模式的代码如下

复制代码
1  HRESULT hr;
2 
3    //  Get adapter display mode
4  D3DDISPLAYMODE mode;
5  if  (FAILED(hr  =  lpDevice -> GetDisplayMode( 0 & mode)))
6       return  hr;
7 
复制代码

下面开始创建表面,这个表面是对应整个屏幕的

Code

接下来获取屏幕对应的数据,这个函数实际上是将显存中的数据拷贝到系统内存中

复制代码
1  //  Get the screen data
2  if  (FAILED(hr  =  lpDevice -> GetFrontBufferData( 0 , surf)))
3  {
4      surf -> Release() ;
5       return  hr ;
6  }
7 
复制代码

接下来我们判断是截取窗口还是截取屏幕,很简单,只需判断hWnd是否为NULL即可,如果是截取窗口则设置窗口对应的矩形区域即可

Code

最后一步,保存截图!

复制代码
1  //  Save the screen date to file
2  hr  =  D3DXSaveSurfaceToFile(fileName, D3DXIFF_BMP, surf, NULL, rect);
3 
4  surf -> Release() ;
5 
6  return  hr ;
7 
复制代码

完整代码

Code

那么如何实现任意区域截屏呢,我想大家已经想到了,假设使用鼠标拖拽的方法截图,记下鼠标按下和抬起时的坐标,构造一个RECT,然后传递给D3DXSaveSurfaceToFile函数就可以了,需要注意到是,由于鼠标拖拽到方向是任意的,所以在构造RECT的时候要注意right < left或者bottom < top 的情况,用下面的方法可以处理

Code

happy coding!

本文转自zdd博客园博客,原文链接:http://www.cnblogs.com/graphics/archive/2009/11/25/1610914.html,如需转载请自行联系原作者

相关文章
|
Rust 安全 开发者
Rust之旅:打造并发布你的首个Rust库
本文将引导读者走进Rust的世界,从基础概念讲起,逐步深入到如何创建、测试、打包和发布自己的Rust库。通过实际操作,我们将理解Rust的独特之处,并学会如何分享自己的代码到Rust社区,从而为开源世界做出贡献。
|
文字识别 Java API
文字识别OCR里这些包
【2月更文挑战第7天】文字识别OCR里这些包
540 1
|
机器学习/深度学习 文字识别 算法
【OCR学习笔记】2、OCR图像预处理(上)
【OCR学习笔记】2、OCR图像预处理(上)
2464 0
|
API Python Windows
对 Python 获取屏幕截图的 4 种方法详解
对 Python 获取屏幕截图的 4 种方法详解
|
Java Maven
IDEA 2018 2020 2021 2022 各版本对Maven版本兼容问题汇总
Maven3.6.3版本兼容问题 错误信息如下: 测试范围如下图: 注意:针对一些老项目 还是尽量采用 3.6.3版本,针对idea各个版本的兼容性就很兼容 0.IDEA 2022 兼容maven 3.8.1及之前的所用版本 1.IDEA 2021 兼容maven 3.8.1及之前的所用版本 2.IDEA 2020 兼容Maven 3.6.3及之前所有版本 3.IDEA 2018 兼容Maven3.6.1及之前所有版本
5319 0
IDEA 2018 2020 2021 2022 各版本对Maven版本兼容问题汇总
|
1月前
|
人工智能 Linux API
5分钟上手龙虾AI!OpenClaw 阿里云/Windows/macOS/Linux部署+免费多模型接入(MiniMax、Claude、百炼)
2026年,OpenClaw(业内昵称“龙虾AI”)凭借**真正执行任务、全平台运行、数据本地可控、支持多模型自由切换**等核心优势,成为个人与轻量化团队首选的开源AI助手。它不再是只能对话的聊天机器人,而是可以直接处理邮件、管理日程、整理文件、生成代码、监控内容、自动备份的**全天候数字员工**。无论你是办公人群、开发者、自媒体,还是只想拥有一个安全高效的私人助理,OpenClaw都能在几分钟内搭建完成,并通过免费大模型直接投入使用。
791 0
|
Java API PHP
阿里巴巴参数获取API
阿里巴巴的参数获取API流程包括:1. 注册并认证开发者账号;2. 创建应用,获取API密钥;3. 阅读API文档,了解请求参数和返回格式;4. 编写代码调用API,如使用Python请求商品详情;5. 注意API类型及其参数,遵守数据使用规则和法律法规。
|
API Python Windows
python3应用windows api对后台程序窗口及桌面截图并保存的方法
python3应用windows api对后台程序窗口及桌面截图并保存的方法
1317 1
|
Java Apache Windows
Jmeter和JDK下载安装及环境变量配置详细教程
Jmeter和JDK下载安装及环境变量配置详细教程,检验是否安装java环境,若无java环境,先下载安装JDK并配置环境变量;再下载安装Jmeter并配置环境变量,Windows系统双击jmeter.bat文件启动Jmeter,或者在cmd中输入:jemter可正常启动jmeter的GUI界面,则jmeter安装及环境变量配置正常。。。
13131 2
Jmeter和JDK下载安装及环境变量配置详细教程
|
Rust 安全 物联网
30天拿下Rust之前世今生
Rust 是一种关注安全与效能的系统级编程语言,由 Mozilla 研究员 Graydon Hoare 于 2006 年发起,旨在解决 C++ 的内存安全与并发难题。通过独特的所有权模型和借用检查机制,Rust 消除了传统语言中的许多安全隐患,实现了内存安全且无运行时垃圾回收。Rust 在 2015 年发布 1.0 版本后迅速崛起,被广泛应用于系统编程、网络服务、浏览器引擎乃至游戏开发等多个领域。其高效的性能、强大的类型系统及丰富的生态系统使其成为开发者心中的新宠。随着技术的进步,Rust 预计将在更多项目中获得应用,并逐渐成为主流选择,特别是在云服务、分布式系统和安全性要求极高的场景中。
336 5