本文介绍如何配置 Win2D 的 XAML 控件使用的分辨率。 这解释了如何:
- 使 Win2D 控件以固定分辨率运行。
- 调整 DPI 设置以减少像素数,从而提高性能。
分辨率和控制组件大小调整
本文档中使用的“分辨率”是位图大小的另一个单词。 它由宽度和高度组成。
Win2D 的 XAML 控件绘制的对象具有分辨率。 它们也有 DPI。 对象的 DPI 是用于测量在绘制对象时其像素密度的指标。 DPI 的行为类似于比例因子- 高 DPI 会增加构成所绘制对象的像素数。 另一方面,降低某个物体的 DPI 意味着它将占用更少的像素。 有关 Win2D 如何通常处理 DPI 的更多信息,请参阅 此页面。
与 DPI 无关的大小有时称为“逻辑大小”。 与 DPI 相关的大小(以像素为单位)称为“物理大小”。
在解析和大小调整方面,加载控件时的默认行为为:
- 控件的逻辑大小由其布局确定,由它位于 XAML 树中的位置确定。
- 从环境中查询 DPI。 控件的 DPI 设置为该状态。
- 构成控件可绘制区域的物理像素量取决于控件的大小,按其 DPI 缩放。
- 在高 DPI 上,与逻辑大小相比,物理大小将更大(更多像素)。
- 在低 DPI 上,与逻辑大小相比,物理大小将更小(更少像素)。
- 在默认 DPI 上,可绘制区域的物理大小和逻辑大小相同。
- 控件的绘图资源(
CanvasImageSource的CanvasControl,CanvasVirtualImageSource的CanvasVirtualControl和CanvasSwapChain的CanvasAnimatedControl)设置为与控件的大小和 DPI 匹配。
大多数 Win2D 操作处于 dip(DPI 无关单位)中,Win2D 的 XAML 控件的绘图资源会自动调整大小,以考虑 DPI。 这意味着应用程序通常可以忽略 DPI。 除非另行指定,否则大小和坐标始终与 DPI 无关。 应用程序可以对各种大小和坐标进行硬编码,以将内容绘制到控件中,当应用程序在不同 DPI 环境中运行时,内容会进行缩放。
但对于某些应用程序,默认行为是不够的。 本文概述了几个情境,其中默认值不够用,以及应用可以采取哪些措施来解决问题。
场景:控件的内容需要是固定的低于正常分辨率的分辨率
例如,在始终以固定的 640x480 分辨率呈现的 2D 子画面游戏中,无论它运行的实际显示硬件如何,都可能出现这种情况。
解决此问题根本不需要编写任何新的 Win2D 代码。
使用 Viewbox XAML 对象,可以约束其子视觉元素的大小,自动添加缩放,并根据需要添加信箱或边框以保持纵横比。
只需确保 CanvasControl、CanvasVirtualControl 或 CanvasAnimatedControl 是 ViewBox的子元素,并限制该控件的大小。
例如,若要将控件的大小限制为 320 像素宽,且高度为 224 像素,而不考虑 DPI,而不是:
<canvas:CanvasAnimatedControl/>
用:
<Viewbox>
<canvas:CanvasAnimatedControl Width="320" Height="224"/>
</Viewbox>
如果应用不应通过添加装箱/支柱框来保留纵横比,则添加 Stretch 属性:
<Viewbox Stretch="Fill">
<canvas:CanvasAnimatedControl Width="320" Height="224"/>
</Viewbox>
请注意,Viewbox 元素执行的缩放不能保证对内插模式的任何控制。 筛选方法可能类似于 CanvasInterpolationMode.Linear或类似的形式。 如果你的应用需要特定的插值模式,则不要将 ViewBox 与固定大小的控件一起使用。 而是绘制到中间的固定大小 CanvasRenderTarget,并使用所需的内插模式将缩放的中间体绘制到目标。
场景:应用在高分辨率下无法很好地执行
某些设备具有非常高分辨率的显示器,但其图形处理单元不够强大,无法使许多像素流畅地进行动画处理。 开发人员可能无法在未经测试的情况下立即了解其应用在这些设备上的表现。
一个选项是使用控件的 DpiScale 属性来减少控件的 DPI。
例如,若要在半分辨率下修复控件,请使用:
<canvas:CanvasAnimatedControl DpiScale="0.5" />
实际 DPI 比例系数取决于应用的需求。 一个选项是计算一个比例系数,该比例因子将修复应用的 DPI 为 96,且不会更高。
例如:
float dpiLimit = 96.0f;
if(control.Dpi > dpiLimit)
{
control.DpiScale = dpiLimit / control.Dpi;
}
为了确保此设置在 DPI 更改中有效,应用程序应订阅 DisplayInformation.DpiChanged,并在处理程序中使用此逻辑针对新 DPI 设置 DPI 比例。
这会节省应用一定的性能负担,这是因为用户可能在高 DPI 显示器上无法轻易察觉到分辨率降低的情况。
在以低于原生分辨率控制资源执行缩放时,无法保证对插值模式的控制,这与上述提到的 ViewBox 类似。 如果你的应用需要特定的内插模式,请改用中间步骤来替代。