当前位置: 首页 > news >正文

FFMPEG录屏(17)--- 使用 DwmRegisterThumbnail 捕获指定窗口图像数据

使用 DwmRegisterThumbnail 捕获指定窗口图像数据

在 Windows 平台上,捕获指定窗口的图像数据可以通过多种方法实现,其中一种高效的方法是使用 [DwmRegisterThumbnail] 本文将介绍如何使用 [DwmRegisterThumbnail] 捕获窗口图像数据,并提供一个完整的示例代码。

前提条件

在开始之前,请确保您的开发环境满足以下条件:

  1. Windows Vista 或更高版本(因为 DWM API 在 Windows Vista 中引入)。
  2. 安装了 Visual Studio 或其他支持 Windows API 开发的编译器。

步骤

1. 包含必要的头文件

首先,包含必要的头文件:

#include <dwmapi.h>
#include <windows.h>
#include <iostream>
2. 检查 DWM 是否支持

在使用 DWM API 之前,检查当前系统是否支持 DWM:

bool is_dwm_supported() {HINSTANCE dwmapi = ::LoadLibraryW(L"dwmapi.dll");if (dwmapi != nullptr) {::FreeLibrary(dwmapi);return true;}return false;
}
3. 注册缩略图

使用 DwmRegisterThumbnail 注册窗口的缩略图:

HTHUMBNAIL register_thumbnail(HWND dest_window, HWND src_window) {HTHUMBNAIL thumbnail_id = nullptr;if (FAILED(::DwmRegisterThumbnail(dest_window, src_window, &thumbnail_id))) {std::cerr << "Register thumbnail failed: " << GetLastError() << std::endl;return nullptr;}return thumbnail_id;
}
4. 更新缩略图属性

设置缩略图的属性,例如可见性、透明度等:

bool update_thumbnail_properties(HTHUMBNAIL thumbnail_id, int width, int height) {DWM_THUMBNAIL_PROPERTIES properties = {};properties.fVisible = TRUE;properties.fSourceClientAreaOnly = FALSE;properties.opacity = 180; // 255 * 0.7properties.dwFlags = DWM_TNP_VISIBLE | DWM_TNP_RECTDESTINATION | DWM_TNP_SOURCECLIENTAREAONLY;properties.rcDestination = {0, 0, width, height};if (FAILED(::DwmUpdateThumbnailProperties(thumbnail_id, &properties))) {std::cerr << "Update thumbnail properties failed: " << GetLastError() << std::endl;return false;}return true;
}
5. 捕获窗口图像数据

使用 GDI 或其他方法捕获窗口图像数据:

bool capture_window_image(HWND window, int width, int height, uint8_t** data) {// 使用 GDI 或其他方法捕获图像数据// 这里省略具体实现return true;
}
6. 完整示例

以下是一个完整的示例代码,展示了如何使用 DwmRegisterThumbnail 捕获指定窗口的图像数据:

#include <dwmapi.h>
#include <windows.h>
#include <iostream>bool is_dwm_supported() {HINSTANCE dwmapi = ::LoadLibraryW(L"dwmapi.dll");if (dwmapi != nullptr) {::FreeLibrary(dwmapi);return true;}return false;
}HTHUMBNAIL register_thumbnail(HWND dest_window, HWND src_window) {HTHUMBNAIL thumbnail_id = nullptr;if (FAILED(::DwmRegisterThumbnail(dest_window, src_window, &thumbnail_id))) {std::cerr << "Register thumbnail failed: " << GetLastError() << std::endl;return nullptr;}return thumbnail_id;
}bool update_thumbnail_properties(HTHUMBNAIL thumbnail_id, int width, int height) {DWM_THUMBNAIL_PROPERTIES properties = {};properties.fVisible = TRUE;properties.fSourceClientAreaOnly = FALSE;properties.opacity = 180; // 255 * 0.7properties.dwFlags = DWM_TNP_VISIBLE | DWM_TNP_RECTDESTINATION | DWM_TNP_SOURCECLIENTAREAONLY;properties.rcDestination = {0, 0, width, height};if (FAILED(::DwmUpdateThumbnailProperties(thumbnail_id, &properties))) {std::cerr << "Update thumbnail properties failed: " << GetLastError() << std::endl;return false;}return true;
}bool capture_window_image(HWND window, int width, int height, uint8_t** data) {// 使用 GDI 或其他方法捕获图像数据// 这里省略具体实现return true;
}int main() {if (!is_dwm_supported()) {std::cerr << "DWM is not supported on this system." << std::endl;return -1;}HWND src_window = ::FindWindow(nullptr, L"Source Window Title");HWND dest_window = ::CreateWindowEx(WS_EX_LAYERED, L"STATIC", L"Destination Window",WS_POPUP | WS_VISIBLE, 0, 0, 800, 600, nullptr, nullptr,nullptr, nullptr);if (!src_window || !dest_window) {std::cerr << "Failed to find or create window." << std::endl;return -1;}HTHUMBNAIL thumbnail_id = register_thumbnail(dest_window, src_window);if (!thumbnail_id) {return -1;}if (!update_thumbnail_properties(thumbnail_id, 800, 600)) {::DwmUnregisterThumbnail(thumbnail_id);return -1;}uint8_t* data = nullptr;if (!capture_window_image(dest_window, 800, 600, &data)) {::DwmUnregisterThumbnail(thumbnail_id);return -1;}// 处理捕获的图像数据// ...::DwmUnregisterThumbnail(thumbnail_id);return 0;
}

总结

通过 [DwmRegisterThumbnail] API,我们可以高效地捕获指定窗口的图像数据。本文介绍了如何检查 DWM 支持、注册缩略图、更新缩略图属性以及捕获窗口图像数据的完整过程。希望这篇文章对您有所帮助。

代码地址

traa

ps
我偷懒了,这个文章是根据代码用copilot自动生成的,看起来还行啊,步骤什么都有了

相关文章:

FFMPEG录屏(17)--- 使用 DwmRegisterThumbnail 捕获指定窗口图像数据

使用 DwmRegisterThumbnail 捕获指定窗口图像数据 在 Windows 平台上&#xff0c;捕获指定窗口的图像数据可以通过多种方法实现&#xff0c;其中一种高效的方法是使用 [DwmRegisterThumbnail] 本文将介绍如何使用 [DwmRegisterThumbnail] 捕获窗口图像数据&#xff0c;并提供一…...

点亮一个LED(51)

目录 1.LED介绍 2.硬件电路 3.程序设计 3.1.点亮一颗LED 3.2.LED闪烁 3.3.LED流水灯实现 1.LED介绍 发光二极管也具有二极管普遍的特性单向导电性&#xff0c;有阳极和阴极之分 &#xff0c;上图左侧式插件式LED &#xff0c;长的引脚是阳极&#xff1b;左侧是贴片式的带…...

Flink窗口分配器WindowAssigner

前言 Flink 数据流经过 keyBy 分组后&#xff0c;下一步就是 WindowAssigner。 WindowAssigner 定义了 stream 中的元素如何被分发到各个窗口&#xff0c;元素可以被分发到一个或多个窗口中&#xff0c;Flink 内置了常用的窗口分配器&#xff0c;包括&#xff1a;tumbling wi…...

【Tinymce】富文本编辑器在vue项目中的使用;引入付费格式刷,上传视频、图片

引言 富文本编辑器有很多&#xff0c;对比了一下&#xff0c;还是决定用tinymce&#xff08;号称宇宙最强&#xff09;&#xff0c;基础的插件确实好用&#xff0c;但是一些更好用的插件&#xff0c;比如格式刷等都是高级版&#xff08;付费&#xff09;&#xff0c;当然也有人…...

Java实现简单的5阶m序列密钥生成

选择5阶本原多项式&#xff1a;x^5 x^2 1,初始值为{1,0,0,1,1}&#xff0c;易得&#xff0c;递推公式为&#xff1a;ak ak-5 ⊕ ak-2 &#xff0c;其中k≥5。于是可以写出下面这段代码&#xff1a; class BitsEncode {public static void main(String[] args) {//初始化数组…...

013_django基于大数据的高血压人群分析系统2024_dcb7986h_055

目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍&#xff1a;CodeMentor毕业设计领航者、全网关注者30W群落&#xff0c;InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者&#xff0c;博客领航之星、开发者头条/腾讯云/AW…...

OpenCV高级图形用户界面(21)暂停程序执行并等待用户按键输入函数waitKey()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 等待按键 该函数 waitKey 在 delay≤0 时无限等待按键事件&#xff0c;或者在 delay 为正数时等待 delay 毫秒。由于操作系统在切换线程时有最小…...

其他css的用途

1.animation-fill-mode: backwards; //避免了在动画开始前元素的突然显现&#xff0c;动画必要。 2.用rem响应式字体大小&#xff0c;可以在html样式定义font-size?(例10px&#xff0c;62.5%(100%是16px))。然后样式就可以用rem代替px。 3.color: transparent;: 这行代码将文…...

json路径 [‘a‘].b.c[0].d[‘1‘].f,具体代表什么意思

JSON路径是一种用于从JSON对象中提取数据的表达方式。你给出的路径 [a].b.c.d[1].f 代表了如何逐层访问JSON对象中的数据。让我们逐步解析这个路径&#xff1a; ‌[a]‌&#xff1a; 表示访问JSON对象的根元素中键为 a 的值。使用方括号 [] 通常意味着这个键是一个字符串&#…...

等保测评:如何进行有效的安全合规性审查

等保测评&#xff08;信息安全等级保护测评&#xff09;是一项至关重要的安全合规性审查工作&#xff0c;旨在帮助组织保障信息系统的安全性、合规性&#xff0c;有效应对安全风险&#xff0c;提升整体安全防护水平。下面将从等保测评的流程、意义、应用场景&#xff0c;以及实…...

FFmpeg 4.3 音视频-多路H265监控录放C++开发二 : 18.04ubuntu安装,linux 下build ffmpeg 4.3 源码 并测试

测试环境 ubuntu 18.04 64 位&#xff0c;安装vmware and ubuntu 安装后调整 分辨率&#xff1a; 让windows 可以和 linux 互相复制黏贴 sudo apt-get autoremove open-vm-tools sudo apt-get update sudo apt-get install open-vm-tools-desktop 一直Y reboot 依赖安装 sud…...

将两张图片的不同标记出来

差异过于细微&#xff0c;阈值设置不当&#xff1a;您的差异可能是颜色或位置的微小变化&#xff0c;当前的阈值和处理方式可能不足以检测到这些细微差异。 图像配准不够精确&#xff1a;由于两张图片内容高度相似&#xff0c;特征点匹配可能存在误差&#xff0c;导致图像对齐…...

HarmonyOS开发(State模型)

一、State模型概述 FA&#xff08;Feature Ability&#xff09;模型&#xff1a;从API 7开始支持的模型&#xff0c;已经不再主推。 Stage模型&#xff1a;从API 9开始新增的模型&#xff0c;是目前主推且会长期演进的模型。在该模型中&#xff0c;由于提供了AbilityStage、Wi…...

在 WPF 中使用 OpenTK:从入门到进阶

一、引言 WPF&#xff08;Windows Presentation Foundation&#xff09;是微软推出的用于创建丰富的桌面应用程序用户界面的框架。OpenTK 则为我们提供了强大的图形处理能力&#xff0c;包括 3D 图形渲染、数学计算等功能。将两者结合起来&#xff0c;可以在 WPF 应用程序中实…...

【最新华为OD机试E卷-支持在线评测】水仙花数(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…...

C# WinForm 用名字name字符串查找子控件

工作上遇到界面控件太多&#xff0c;需要对一些控件批量处理。虽然可以用代码批量控制&#xff0c;但要么是建立数组集合把所有要处理的控件放进去循环处理&#xff0c;要么是一个一个列出来修改属性。 但我大多数要求改的控件命名上是有规律的&#xff0c;所有只需要循环拼接字…...

Ubuntu下安装并初始化Git同时添加SSH密钥

在 Ubuntu 上可以使用以下命令安装git&#xff1a; sudo apt-get update sudo apt-get install git 在 Ubuntu 下安装好 Git 之后&#xff0c;接下来可以进行一些基本的配置和操作&#xff0c;以便更好地使用 Git。 1. 配置 Git 用户信息 在使用 Git 进行版本控制前&#x…...

好用的AI工具:探索智能生活的无限可能

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《热点时事》 期待您的关注 目录 引言 一&#xff1a;常用AI工具 1. 语音助手&#xff08;如Siri、小爱同学&#xff09; 2. 智…...

-bash: conda: command not found

-bash: conda: command not found 说明当前的终端环境中没有找到 conda 命令&#xff0c;可能是因为 Conda 没有安装&#xff0c;或者当前的环境变量中没有包含 Conda 的路径。 解决方法 确保 Conda 已安装 确认 Conda 路径是否添加到环境变量 如果 Conda 已安装&#xff0c;…...

STM32-CubeIDE用串口通讯

USART串口通讯 一、轮询模式 1.设置所接引脚为UART异步模式 选择完成CTRLS保存。 2.编写测试代码&#xff08;自动发送hello world&#xff09; 在mian函数里面编写代码 原函数 调用函数&#xff0c;需要数据类型一致&#xff0c;使用函数通过串口发送数组里面的数据 打开串…...

告别命令行恐惧!用Docker Desktop可视化界面5分钟搞定Ollama部署(附端口映射避坑指南)

告别命令行恐惧&#xff01;用Docker Desktop可视化界面5分钟搞定Ollama部署&#xff08;附端口映射避坑指南&#xff09; 如果你对命令行操作感到头疼&#xff0c;却又想快速体验Ollama的强大功能&#xff0c;这篇文章正是为你准备的。我们将完全避开复杂的终端指令&#xff…...

告别Telnet和Jmeter!用Apifox 2.3.24一站式调试Dubbo 3.x接口(保姆级Nacos集成教程)

告别Telnet和Jmeter&#xff01;用Apifox 2.3.24一站式调试Dubbo 3.x接口&#xff08;保姆级Nacos集成教程&#xff09; 如果你正在使用Dubbo 3.x构建微服务&#xff0c;可能已经发现传统的调试工具越来越力不从心。Telnet虽然简单但功能有限&#xff0c;Jmeter需要额外插件且对…...

云端炼丹新思路:在趋动云Linux环境无缝运行秋葉aaaki的SD整合包

1. 为什么要在云端运行Stable Diffusion整合包 最近两年AI绘画工具爆发式增长&#xff0c;其中Stable Diffusion凭借开源免费、效果出众等优势成为最受欢迎的选项之一。B站知名UP主秋葉aaaki制作的整合包更是让普通用户也能轻松上手&#xff0c;解压即用。但现实情况是&#xf…...

小团队福音:用两台服务器搞定Redis高可用(Keepalived+互为主从配置)

小团队福音&#xff1a;用两台服务器构建轻量级Redis高可用架构 在初创公司和小型技术团队中&#xff0c;服务器资源往往捉襟见肘。当业务需要Redis作为缓存或数据库时&#xff0c;传统的高可用方案如哨兵模式需要至少三台服务器&#xff0c;这对资源有限的团队来说可能过于奢侈…...

大模型幻觉问题:RAG检索增强与约束生成解决方案

GPTQ 和 AWQ 都是量化技术&#xff0c;它们有什么区别&#xff1f;在什么场景下选哪种&#xff1f; GPTQ&#xff1a;是一种基于二阶信息&#xff08;海森矩阵&#xff09;的层级量化方法&#xff0c;它通过计算权重对误差的敏感度&#xff0c;优先保留重要的权重。侧重于整体权…...

SDD基于规范编程-OpenSpec及SuperPowers沙

智能体时代的代码范式转移与 C# 的战略转型 传统的 C# 开发模式&#xff0c;即所谓的“工程导向型”开发&#xff0c;要求开发者创建一个复杂的项目结构&#xff0c;包括项目文件&#xff08;.csproj&#xff09;、解决方案文件&#xff08;.sln&#xff09;、属性设置以及依赖…...

Rust 时间处理神器:chrono 从入门到实战

Rust 时间处理神器&#xff1a;chrono 从入门到实战 在 Rust 生态中&#xff0c;chrono 凭借其遵循 ISO 8601 标准、支持时区、类型安全且性能优异的特性&#xff0c;成为了 Rust 开发者的首选工具。本文将从入门到进阶&#xff0c;并结合实际开发场景带你全面掌握 chrono 的使…...

ESPS USB MSC 调试全过程记录戎

背景 在软件开发的漫长旅途中&#xff0c;"构建"这个词往往让人又爱又恨。爱的是&#xff0c;一键点击&#xff0c;代码变成产品&#xff0c;那是程序员最迷人的时刻&#xff1b;恨的是&#xff0c;维护那一堆乱糟糟的构建脚本&#xff0c;简直是噩梦。 在很多项目中…...

基于SpringBoot + Vue的城市供水管网爆管预警系统(角色:用户、维护人员、管理员)

文章目录前言一、详细操作演示视频二、具体实现截图三、技术栈1.前端-Vue.js2.后端-SpringBoot3.数据库-MySQL4.系统架构-B/S四、系统测试1.系统测试概述2.系统功能测试3.系统测试结论五、项目代码参考六、数据库代码参考七、项目论文示例结语前言 &#x1f49b;博主介绍&#…...

收藏!大模型岗位真相:看似暴涨,实则与多数程序员无关(小白必看)

一、虚假的岗位增长&#xff1a;AI岗位全在上游&#xff0c;小白根本够不到 很多程序员&#xff08;尤其是刚入门的小白&#xff09;都在焦虑&#xff1a;明明全网都在说AI风口、大模型岗位暴涨&#xff0c;为什么自己投简历却石沉大海&#xff1f;其实真相很扎心——AI岗位不是…...