【问题标题】:How is Windows 10 Night Light implemented?Windows 10 夜灯是如何实现的?
【发布时间】:2020-01-31 22:39:37
【问题描述】:

Windows 10 具有更改屏幕色温的功能,称为夜灯。这是一种减少蓝光的功能。

我想使用 Windows API 在 C++ 中实现此功能的克隆。但不知道该怎么做。

  • 如何使用 win api 访问屏幕并更改其在系统范围内显示的内容?它必须是资源高效的。
  • 我们能否仅将其应用于给定窗口,而不是整个屏幕?

【问题讨论】:

  • "...访问屏幕的规范方法是什么..." C++ 没有直接访问屏幕的方法,您必须使用第 3 方 API /图书馆。对于 WinAPI 使用 docs.microsoft.com/en-us/windows/win32/api/…
  • 甚至使用 Windows API?操作系统应该能够访问屏幕
  • 我使用关键字“windows 10 night light api”进行了互联网搜索,并找到了Get status of night light mode in Windows 10。你最近上网了吗?
  • @ThomasMatthews,您阅读过实际问答的 cmets 吗? ;-) 那里没有任何用处。

标签: c++ windows winapi


【解决方案1】:

操作系统允许你做它自己做的事情并不总是一个有效的期望。仅仅因为“操作系统应该能够访问屏幕”并不意味着(在用户空间中)应该能够做到这一点。并且可以肯定的是,在 Windows 下,您没有不受限制的屏幕访问,尤其是因为 DRM:有一个 protected media path (PMP) 用于受保护的视频和音频内容,您将无法从任意进程中嗅探它。

因此:无论您通过访问屏幕内容实现的任何夜灯,一旦显示任何受保护的内容(例如来自 Netflix、Hulu、Youtube Red、系统 DVD 播放器、蓝光播放器等。要绕过 PMP,您需要编写驱动程序,使用 EV 代码签名证书对其进行签名,然后将其提交给自动 attestation signing by Microsoft。而且你不敢把它放到网络上,因为微软会将该驱动程序列入黑名单(即它在内核中的存在会导致使用 PMP 的应用程序拒绝播放受保护的内容),而且可能很快。

除此之外,Windows 可以通过多种方式实现它,但我们不在乎,因为我们没有编写 Windows Night Light 组件的直接替代品。我们只能访问用户空间。下面是我们要处理的内容:

  1. Windows 本身使用“伽马渐变”系统执行显示器色彩空间校准:一个查找表,过去主要用于显示器响应的线性化,随后用作厨房水槽。这些 API 分为三代:

    • 最兼容旧版的方式是使用自 Windows 2000 起支持的 Windows Color System API。要使用的函数是 SetDeviceGammaRamp。有一个警告:Windows 不允许过度压缩颜色,而且它允许的内容非常随意。如果您尝试做“太多”,这一系列 API 可能会失败。

    • 另一个高度兼容的 API 将在 Direct3D 9 中(从 Windows 98 和 XP 开始可用)。提供SetGammaRamp,数据表格式与上述SetDeviceGammaRamp相同。

    • 另一个高度兼容的 API 将位于 Direct3D 10-12 的 DirectX Graphics Interface - DXGI,特别是 IDXGIOutput::SetGammaControl。此版本从 Windows Vista 开始可用,因此在当前 (2020) 支持的 Windows 版本上可用。

  2. 下一个最兼容的方法是使用Magnification API

  3. 最后一种方法(仅在您自己的应用程序窗口上工作)是应用shader to your window

【讨论】:

    【解决方案2】:

    这可以使用色彩校正方案来模拟。有这个开源项目,DisplayCAL。它是一种校准器,可用于其他目的,还允许使用各种校准器设备。本质上,所有图形输出设备都设计了一个数字滤波器,它将源 RGB 转换为屏幕 RGB,并且有可能对其进行更改。 Linux 在某些发行版中有类似的东西。

    【讨论】:

      【解决方案3】:

      Microsoft 提供了Monitor Configuration functions,它使用Display Data Channel Command Interface (DDC/CI) 将命令发送到监视器。虽然我不确定他们是这样做的,但这似乎是最有可能的方法。

      此 API 与物理监视器句柄一起使用,这意味着它适用于整个监视器的屏幕,而不是监视器上显示的单个窗口。

      您可以使用监视器配置功能来获取信息 从监视器和更改监视器的设置。你可以使用这些 功能:

      • 更改显示器的几何设置,例如显示器的宽度和高度。
      • 更改图像设置,例如亮度和对比度。
      • 将显示器的设置重置为出厂默认设置。
      • 对显示器进行消磁。

      在内部,监视器配置函数使用显示数据 用于向监视器发送命令的通道命令接口 (DDC/CI)。

      监视器配置主题提到:

      要开发监视器配置,您需要这些标头:

      查看包含函数列表的 Windows 应用程序开发主题 Monitor Configuration Functions,您可能会发现其中一些有用。

      上述所有高级监视器配置 API 函数似乎都有以下要求:

      支持的最低客户端 Windows Vista [仅限桌面应用]

      支持的最低服务器 Windows Server 2008 [仅限桌面应用]

      目标平台窗口

      头文件 highlevelmonitorconfigurationapi.h

      库 Dxva2.lib

      DLL Dxva2.dll

      它们都需要通过GetPhysicalMonitorsFromHMONITOR()GetPhysicalMonitorsFromIDirect3DDevice9() 函数获得的物理监视器句柄。

      【讨论】:

        猜你喜欢
        • 2017-09-06
        • 2016-12-13
        • 2016-03-24
        • 2012-04-29
        • 1970-01-01
        • 2016-03-23
        • 2020-03-21
        • 2015-11-27
        • 2011-06-20
        相关资源
        最近更新 更多