c# - 完整 Windows 桌面的实时视频处理

标签 c# c++ windows

<分区>

我想为完整的 Windows 桌面添加动态视频效果。

我希望能够将屏幕变成灰色,斜切边缘并添加一些扫描线,使它看起来像一个旧的 CRT 屏幕,或者使屏幕出现故障,就像他们在电影中显示被黑系统一样了解技术等

效果本身超出了这个问题的范围。这个问题是如何应用它们,即如何获取 Windows 生成的桌面图像,应用我的效果,并在同一显示器上显示结果。

我知道几种可行的方法。

  1. 连接到绘制内容的 WinAPI 调用。
  2. 创建一个假的辅助显示器,使其成为主要显示设备,从中获取视频流,应用我的效果,并在真实显示器上呈现
  3. 创建应用效果的自定义显示驱动程序。

它们都有缺点:复杂性、驱动程序签名要求、复杂的设置。有没有更好的方法来实现我想要的?

最佳答案

1 很难,太多不同的 API。

2 困难的部分是制作假显示器。如果您改为购买一个 10 美元的设备,称为“HDMI 虚拟插头”,它将变得相对简单,具有 100% 记录的 API。使用桌面复制 API 获取显示器 1 的纹理,应用任何你想要的效果并在显示器 2 上显示。如果你想要好的性能,你最好完全在 GPU 上实现处理,例如使用自定义像素着色器渲染四边形。

3 会工作,但很难做到。

还有一个办法。实现和使用未记录的 API 很棘手,但根据我的经验,它非常可靠,至少在 Windows 7 上是这样。编写一个 DLL,将其自身注入(inject) dwm.exe。那是一个 windows 进程“桌面 windows 管理器”,它组成了桌面上可见的任何东西。 DLL 注入(inject)后,创建一个新线程,在该线程中调用 D3D11CreateDeviceAndSwapChain,然后使用例如MinHook拦截 Present,理想情况下还拦截 IDXGISwapChain 接口(interface)的 ResizeBuffers 方法。如果成功,dwm.exe 将在每次显示帧或桌面分辨率更改时调用 DLL 中的函数。然后,在目前的功能中你可以做你的事情,例如添加另一个实现您的效果的渲染 channel ,然后调用原始实现以实际将结果呈现到桌面。

这在理论上很容易,但在实践中实现起来却相当棘手。例如。很难调试 dwm.exe,你必须依赖日志记录,或者使用带有远程调试器的虚拟机。这也不能跨 Windows 版本移植。另一个限制是,它不适用于视频游戏等全屏应用程序,它们会绕过 dwm.exe。对于视频游戏,仅适用于“无边框全屏窗口”游戏内设置。

更新:另一种方法,简单得多。创建一个具有逐像素透明度的最顶层全屏窗口。操作系统支持它们数十年,设置 WS_EX_LAYEREDWS_EX_TRANSPARENT 扩展样式位。你将无法进行灰度,因为你只能覆盖你的东西而不能读取下面的内容,但边缘、扫描线和毛刺是完全可行的。为了获得最佳性能,请使用一些以 GPU 为中心的 API 来渲染该窗口,例如C++ 中的 Direct2D 或 D3D。它也更容易调试,要么使用 2 个显示器,要么放置透明窗口,使其在角落占据一个矩形,为 IDE 留出足够的屏幕空间。 Here's an example (不是我的)。

关于c# - 完整 Windows 桌面的实时视频处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57323981/

相关文章:

c# - 调试器无法继续运行该进程。无法开始调试

c# - 如何在 C# SQL 查询中使用 X 列长度对多个列名称进行字符串格式化

c# - 是否可以使用基于属性而不是类型的通用约束?

C#调用Delphi的dll文件

c++ - 在命名空间之外的c++中为外部变量赋值

c++ - 什么是 undefined reference /未解析的外部符号错误,我该如何解决?

c++ - Qt 造物主 : Treat warnings as errors

c++ - 将 VK_CODE 转换为可显示的字符串

php - 如何使 Windows 符号链接(symbolic link)与 mod_php 一起工作?

.net - Windows SDK 7.1 安装失败