由于WPF 图形系统使用与设备无关的单元来支持分辨率和设备无关性,每个与设备无关的像素都会随系统上的每英寸点数 (DPI) 设置自动缩放,我们可以把这种DPI称为系统DPI,按照WPF系统默认设置,每个显示器(或称显示平面,还有可能是投影仪或打印机)在WPF系统中的系统DPI都被默认为是96个单位,数据类型为double类型,而事实上屏幕上所有图像的显示都是由一个个的物理像素实现的,屏幕上每英寸的像素数量称之为PPI,如果物理PPI与系统DPI都是96个,而且都是整数型,那就没有一点问题,但实际情况是随着液晶屏幕成本的下降,大多数显示器的每英寸像素数量越来越多,也就是PPI越来越高,比如苹果最先推出的视网膜屏幕,就高达326PPI,大部分笔记本的PPI数量也都超过96的水平,而且这个发展趋势也越来越明显,所有,个人觉得微软将默认DPI设置为96稍微有点保守,不过微软也一向如此。好了,不说废话了,下面来看看如果DPI和PPI不匹配时WPF是怎么做的。
WPF为了给观众较好的视觉效果,默认提供了抗锯齿功能,这和GDI+的抗锯齿基本原理一致,GDI+是通过线条显色与背景色混色并向外扩展而得到一个模糊化的边缘来实现的,WPF是提供向外扩展的半透明边缘来实现模糊化。由于WPF采用了设备无关单位,当设备DPI大于系统DPI时,可能会产生像素自动扩展问题,这就导致线条自动向外扩展一个像素,并且与边缘相邻的线条颜色变成了半透明,我们先看一下下面的例子:
上图中左边的线条是像素自动扩展后的线条,右边是我们想要的结果,如何来实现呢?WPF给我们提供了几种解决方案:
一、设置像素对齐属性
对于UIElement及其继承对象,WPF都提供了SnapsToDevicePixels属性,SnapsToDevicePixels是布尔类型,将SnapsToDevicePixels设为true即可实现像素对齐功能,效果如上图中右侧线条所示。那么是不是需要设置每一个图形对象的SnapsToDevicePixels呢?答案是不需要ÿ