在XAML格式中显示图像时的模糊伪影
我有一张简单的 图片,是 .svg 格式,使用Inkscape创建。它只是由几条线和表示单元格的砖块组成的网格。我用Inkscape将这张图片转换成XAML,并在我的项目中使用,但效果一点也不清晰。
以下是用Inkscape创建的XAML:
<?xml version="1.0" ?>
<ResourceDictionary xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<DrawingGroup x:Key="grid">
<DrawingGroup.ClipGeometry>
<RectangleGeometry Rect="0.0,0.0,90.0,102.625"/>
</DrawingGroup.ClipGeometry>
<DrawingGroup>
<GeometryDrawing Brush="#ff000000">
<GeometryDrawing.Geometry>
<PathGeometry Figures="M 0 0 H 90 V 102.625 H 0 Z" FillRule="Nonzero"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#ffdfdfdf">
<GeometryDrawing.Geometry>
<PathGeometry Figures="m 77.375 90 h 11 v 11 h -11 z M 64.75 90 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z M 39.5 90 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z M 14.25 90 h 11 v 11 h -11 z M 1.625 90 h 11 v 11 h -11 z m 75.75 -12.625 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z M 77.375 64.75 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m 75.75 -12.625 h 11 v 11 h -11 z m 0 -12.625 h 11 v 11 h -11 z m 0 -12.625 h 11 v 11 h -11 z m 0 -12.625 h 11 v 11 h -11 z m 0 -12.625 h 11 v 11 h -11 z m -12.625 50.5 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z M 64.75 39.5 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z M 64.75 26.875 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z M 64.75 14.25 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z M 64.75 1.625 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z M 39.5 14.25 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z M 39.5 1.625 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z m -12.625 0 h 11 v 11 h -11 z" FillRule="Nonzero"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingGroup>
<DrawingImage Drawing="{StaticResource grid}" x:Key="di_grid"/>
</ResourceDictionary>
下面是它的显示效果:

正如你所见:有些线条很清晰,但并非全部。在屏幕放大镜下会更清楚:

如果我用 SvgToXaml 转换图片,情况也一样。
在Inkscape中尝试“扁平化”这张图片也没有帮助。
我把它在我的项目中作为一个 Resource 使用,试图把整块 DrawingImage 作为 Source 的 Image,甚至提取 PathGeometry 的数值并在一个 Path 元素中使用。都没成功。
使用 UseLayoutRounding 和 SnapsToDevicePixels 也不起作用。
唯一能在不产生模糊的情况下显示这张图片的方式,是把它放大2 到3 倍。但我需要保持原始尺寸:90 x 102.625像素。
我已经为这个问题苦苦挣扎了3 天,已经没有更多可尝试的方法。
如何才能显示出清晰锐利的图像?有什么想法吗?
解决方案
当绘制矢量形状时你的线条会进行抗锯齿处理,这会在你的线条与屏幕像素没有完全对齐时造成一定程度的模糊。你的一些坐标不是整数,这一点也支持这个观点。
因此我的首要建议是为特定分辨率设计你的图像。在Inkscape中显示网格线可以帮助你直观地看到“像素”。确保你的线条与像素网格完美对齐。你还需要确保WPF将你的图像恰好按照这个尺寸绘制。显然,如果你为特定像素分辨率设计矢量图,完全可以把它转换为位图。确保位图图像不以任何方式被缩放,可能更容易。
我不确定 UseLayoutRounding 和 SnapToDevicePixels 是否适用于路径几何中的单个点,因为那样会扭曲图形。你可以尝试指定 RenderOptions.EdgeMode="Aliased"。虽然那应该能强制线条变得清晰,但可能会影响线宽和/或单元格的宽度,从而让图像看起来很奇怪。
如果你希望你的图像在不同分辨率(即DPI)下看起来都不错,你需要做出某种妥协。比如你有一条1 像素宽的线并将其缩放到125%,你可以要么把它绘制成1.25像素宽,并接受一些模糊,要么把它向下取整为1 像素宽,并接受线条比应有的更细。