【发布时间】:2016-11-11 11:53:45
【问题描述】:
为了使我的 WPF 应用程序具有高 DPI 感知能力,我选择使用嵌入式 XAML 矢量图形创建所有内部图形和图标。
但是,我不明白为什么我的 XAML 矢量图形在呈现时是模糊的。这是一个例子。我使用 XAML Path 和 Rectangle 元素绘制了一个简单的软盘图标。下图是以两种不同尺寸呈现的同一个图标,并具有不同的 SnapsToDevicePixels 和 UseLayoutRounding 值(这是我的显示器在 Windows 7 中的原始分辨率为 2048x1152)。
鉴于图标大多是水平和垂直线,它看起来奇怪的模糊。这是较大图标的 600% 缩放视图:
还有更小的图标:
两种尺寸的边缘都不脆。随着SnapsToDevicePixels 的值变化,一些边缘清晰,但其他边缘仍然不清晰。
绘制这样的图标以使它们不会模糊呈现的正确方法是什么?
这是此窗口的 XAML,包括路径数据:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="XAML Path Test" Height="175" Width="525">
<Window.Resources>
<ResourceDictionary>
<Canvas x:Key="icon">
<Path Width="84" Height="83" Canvas.Left="6.5" Canvas.Top="9.5" Stretch="Fill" StrokeThickness="5" StrokeMiterLimit="2.75" Stroke="#FF000000" Fill="#FFFFFFFF" Data="F1 M 9,12L 68.9914,12L 88,31.0086L 88,90L 9,90L 9,12 Z "/>
<Rectangle Width="43" Height="41" Canvas.Left="23.5" Canvas.Top="9.5" Stretch="Fill" StrokeThickness="5" StrokeMiterLimit="2.75" Stroke="#FF000000" Fill="#FF000000"/>
<Rectangle Width="23" Height="31" Canvas.Left="38.5" Canvas.Top="11.25" Stretch="Fill" StrokeThickness="5" StrokeMiterLimit="2.75" Stroke="#FF000000" Fill="#FFFFFFFF"/>
</Canvas>
</ResourceDictionary>
</Window.Resources>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<Rectangle Width="50" Height="50" Margin="10">
<Rectangle.Fill>
<VisualBrush Visual="{StaticResource icon}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Width="50" Height="50" Margin="10" SnapsToDevicePixels="True">
<Rectangle.Fill>
<VisualBrush Visual="{StaticResource icon}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Width="50" Height="50" Margin="10" UseLayoutRounding="True" SnapsToDevicePixels="True">
<Rectangle.Fill>
<VisualBrush Visual="{StaticResource icon}"/>
</Rectangle.Fill>
</Rectangle>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<Rectangle Width="24" Height="24" Margin="10">
<Rectangle.Fill>
<VisualBrush Visual="{StaticResource icon}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Width="24" Height="24" Margin="10" SnapsToDevicePixels="True">
<Rectangle.Fill>
<VisualBrush Visual="{StaticResource icon}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Width="24" Height="24" Margin="10" UseLayoutRounding="True" SnapsToDevicePixels="True">
<Rectangle.Fill>
<VisualBrush Visual="{StaticResource icon}"/>
</Rectangle.Fill>
</Rectangle>
</StackPanel>
</StackPanel>
</Window>
编辑:
按照 Chris W. 的建议,通过将路径 + 矩形包装在 ControlTemplate 中,并使用 Viewbox 调整大小,图像仍然模糊。从左到右,这是未调整大小(画布大小为 100x100),调整为 50,调整为 24:
还有 600% 的缩放视图:
这里是ControlTemplate:
<ControlTemplate x:Key="icon">
<Canvas Width="100" Height="100">
<Path Width="84" Height="83" Canvas.Left="6.5" Canvas.Top="9.5" Stretch="Fill" StrokeThickness="5" StrokeMiterLimit="2.75" Stroke="#FF000000" Fill="#FFFFFFFF" Data="F1 M 9,12L 68.9914,12L 88,31.0086L 88,90L 9,90L 9,12 Z "/>
<Rectangle Width="43" Height="41" Canvas.Left="23.5" Canvas.Top="9.5" Stretch="Fill" StrokeThickness="5" StrokeMiterLimit="2.75" Stroke="#FF000000" Fill="#FF000000"/>
<Rectangle Width="23" Height="31" Canvas.Left="38.5" Canvas.Top="11.25" Stretch="Fill" StrokeThickness="5" StrokeMiterLimit="2.75" Stroke="#FF000000" Fill="#FFFFFFFF"/>
</Canvas>
</ControlTemplate>
以及用法:
<Control Template="{StaticResource icon}"/>
<Viewbox Height="50">
<Control Template="{StaticResource icon}"/>
</Viewbox>
<Viewbox Height="24">
<Control Template="{StaticResource icon}"/>
</Viewbox>
【问题讨论】:
-
我们做了类似的事情,但在我们的例子中,我的一位同事使用 SVG 制作图形,然后将其转换为 XAML 矢量图形。我不知道他是怎么做到的,他是我们团队的 UI 专家。我只是提出这个建议,你也许可以做同样的事情。
-
@Rod 他可能只是在 illustrator 中制作了它们,并使用了 Mike Swanson 的超级方便的花花公子 AI to XAML 插件,或者我认为 Inkscape 也可以导出到 Path XAML。
-
@ChrisW。现在我在 Expression Design 4 中绘制它们并使用复制到 XAML 功能。将来我想在 SVG 中绘制它们并从那里转换为 XAML。
标签: wpf xaml user-interface icons vector-graphics