使用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社区,从而为开源世界做出贡献。
|
机器学习/深度学习 文字识别 算法
【OCR学习笔记】2、OCR图像预处理(上)
【OCR学习笔记】2、OCR图像预处理(上)
2843 0
|
6月前
|
人工智能 Linux API
5分钟上手龙虾AI!OpenClaw 阿里云/Windows/macOS/Linux部署+免费多模型接入(MiniMax、Claude、百炼)
2026年,OpenClaw(业内昵称“龙虾AI”)凭借**真正执行任务、全平台运行、数据本地可控、支持多模型自由切换**等核心优势,成为个人与轻量化团队首选的开源AI助手。它不再是只能对话的聊天机器人,而是可以直接处理邮件、管理日程、整理文件、生成代码、监控内容、自动备份的**全天候数字员工**。无论你是办公人群、开发者、自媒体,还是只想拥有一个安全高效的私人助理,OpenClaw都能在几分钟内搭建完成,并通过免费大模型直接投入使用。
1245 1
|
消息中间件 前端开发 Java
如何开发人事管理系统中的离职管理板块?(附架构图+流程图+代码参考)
在数字化时代,企业人力资源管理趋向全流程、闭环化、数据驱动。人事管理系统(HRMS)涵盖招聘、入职到离职的全生命周期管理,其中离职管理是关键环节,涉及流程规范、交接透明、反馈收集等,能有效降低风险、提升效率。本文以简道云HRMS为例,解析离职管理模块的设计与实现,包括系统架构、核心功能、开发技巧与最佳实践,助力企业优化人力资源管理流程,实现高效、合规、数据驱动的离职管理。
|
API Python Windows
python3应用windows api对后台程序窗口及桌面截图并保存的方法
python3应用windows api对后台程序窗口及桌面截图并保存的方法
1725 1
|
存储 安全 关系型数据库
Blossom:开源私有部署的markdown笔记软件
Blossom 是一款功能强大的开源笔记软件,支持私有部署,可将笔记、图片、个人计划等数据保存在自己的服务器中,并实现实时同步。它还具备动态博客功能,方便记录和分享内容。Blossom 支持多种设备,提供完善的文件管理、快速迁移和丰富的附加功能,是个人知识管理和博客展示的理想选择。
1372 7
Blossom:开源私有部署的markdown笔记软件
|
人工智能 自然语言处理
阿里云logo设计智能生成(一键生成海量LOGO)
阿里云智能logo设计在线生成海量logo,logo可商用也可以申请商标,阿里云logo设计入口在哪里?阿里云开启了二级域名logo.aliyun.com,关于阿里云智能logo设计有多个入口链接,阿里云百科分享阿里云logo设计入口、价格及使用方法:
11977 108
阿里云logo设计智能生成(一键生成海量LOGO)
|
监控 数据可视化 Linux
Qt Model&View&Delegate(模型-视图-代理) 介绍和使用
Qt Model&View&Delegate(模型-视图-代理) 介绍和使用
Qt Model&View&Delegate(模型-视图-代理) 介绍和使用
|
Rust 安全 物联网
30天拿下Rust之前世今生
Rust 是一种关注安全与效能的系统级编程语言,由 Mozilla 研究员 Graydon Hoare 于 2006 年发起,旨在解决 C++ 的内存安全与并发难题。通过独特的所有权模型和借用检查机制,Rust 消除了传统语言中的许多安全隐患,实现了内存安全且无运行时垃圾回收。Rust 在 2015 年发布 1.0 版本后迅速崛起,被广泛应用于系统编程、网络服务、浏览器引擎乃至游戏开发等多个领域。其高效的性能、强大的类型系统及丰富的生态系统使其成为开发者心中的新宠。随着技术的进步,Rust 预计将在更多项目中获得应用,并逐渐成为主流选择,特别是在云服务、分布式系统和安全性要求极高的场景中。
487 5

热门文章

最新文章