如何避免 WPF 抗锯齿?
WPF 的一大问题是抗锯齿。 事实上,这就是 WPF 4.0 中引入 UseLayoutRending 的原因。 但是,在以下示例中它对我不起作用:
<StackPanel UseLayoutRounding="True" TextOptions.TextFormattingMode="Display" >
<Line X1="0" Y1="0" X2="200" Y2="0" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line>
<Line X1="0" Y1="1.5" X2="200" Y2="1.5" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line>
<Line X1="0" Y1="3.5" X2="200" Y2="3.5" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line>
<Line X1="0" Y1="7" X2="200" Y2="7" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line>
<Line X1="0" Y1="9" X2="200" Y2="9" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line>
</StackPanel>
最后两行仍然模糊。 (我使用的是Windows 7)
有什么解决办法吗?
或者是WPF 4.0测试版的一个bug?
One of the big problems with WPF is anti aliasing.
In fact, that's why UseLayoutRending was introduced in WPF 4.0.
However, it does not work for me in the following sample:
<StackPanel UseLayoutRounding="True" TextOptions.TextFormattingMode="Display" >
<Line X1="0" Y1="0" X2="200" Y2="0" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line>
<Line X1="0" Y1="1.5" X2="200" Y2="1.5" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line>
<Line X1="0" Y1="3.5" X2="200" Y2="3.5" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line>
<Line X1="0" Y1="7" X2="200" Y2="7" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line>
<Line X1="0" Y1="9" X2="200" Y2="9" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line>
</StackPanel>
The last two lines are still blurry.
(I am using Windows 7)
Any solution?
Or is it a bug in the beta of WPF 4.0?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在 WPF 中让线条看起来清晰可能相当困难!有时......似乎也需要一点黑魔法!
我认为弗洛埃和金克的答案指向了正确的方向。也就是说,很多时候您会希望将单像素线放在 0.5 像素边界上……考虑到它绘制线的方式(一半在一侧,一半在另一侧)。
但是,它也不总是那么简单。例如,它还取决于周围的 xaml。例如,尝试此代码并在执行时调整大小:
然后,尝试此代码(再次在执行时调整大小):
两个片段之间的唯一区别是第一个在 Lines 上使用 UseLayoutRounding,而第二个在 Lines 上使用 UseLayoutRounding Canvas 容器(然后它的属性也继承到 Lines)。
然而,这种差异产生了一些有趣的结果。当在容器上使用 UseLayoutRounding 时,单个像素线始终保持分布在 2 个像素以上,并且不会四处移动。当直接在线条上使用 UseLayoutRounding 并调整大小时,线条有时会锐利 1 像素……而其他时候则会扩展超过 2 像素。
这让我想到了原始问题中的示例 xaml。对此的一些评论:
比原始海报想要的更多信息。然而,我个人知道在 WPF 中使线条清晰是多么棘手。希望这个信息对某人有帮助!
Getting lines to look sharp in WPF can be quite hard! And some times ... it seems like it takes a bit of black magic too!
I think that floele and Kimke's answers are pointing in correct direction. That is, often times you will want to put single pixel lines on a 0.5 pixel boundary ... given the way that it draws the line (half on one side and half on another).
However, it isn't always that simple either. For example, it also depends on the surrounding xaml. For example, try this code out and resize when you do:
Then, try this code out (again, resize when you do):
The only difference between the two snippets is that the first uses UseLayoutRounding on the Lines while the second uses UseLayoutRounding on the Canvas container (which then also property inherit to the Lines).
However, that difference yields some interesting results. When UseLayoutRounding is used on the container the single pixel lines consistently stay spread out over 2 pixels and they don't move around. When UseLayoutRounding is used on the Lines directly, and you resize, the lines will sometimes be 1 pixel sharp ... and other times will be spead over 2 pixels.
And that brings me to the sample xaml in the original question. A few comments on it:
More info than what the original poster was wanting. However, I personally know how tricky it is to get lines sharp in WPF. Hope this info helps someone!
原因显然更简单。我只在“Pro WPF in VB 2010”中找到了解释,但在 MSDN 上没有找到: http://books.google.de/books?id=F-gMZkAlUDUC&pg=PA334&lpg=PA334
简而言之,
StrokeThickness
将被除以对于形状的两侧,因此StrokeThickness
为 1 等于每侧的厚度为 0.5,并且由于线条只有一侧,因此它的厚度将为 0.5 单位,因此即使使用时也会显得模糊SnapsToDevicePixels=True
。因此只需使用“2”作为 StrokeThickness 即可。您可以使用 4 的
StrokeThickness
来验证这一点,那么线条的厚度将为 2,这不仅仅是“偶然”的单像素偏差。The reason is apparently simpler. I only found an explanation in "Pro WPF in VB 2010" and not on MSDN though: http://books.google.de/books?id=F-gMZkAlUDUC&pg=PA334&lpg=PA334
In short, the
StrokeThickness
will be divided for both sides of a shape, so aStrokeThickness
of 1 equals a thickness of 0.5 for each side, and since the line only has one side, it will be 0.5 units thick and thus appear blurry even when usingSnapsToDevicePixels=True
. So simply use "2" as StrokeThickness.You can verify this by using a
StrokeThickness
of 4, the line will have a thickness of 2 then, which is more than an "accidential" single pixel deviation.您是否尝试将
TextOptions.TextFormattingMode
属性更改为Display
?请参阅此内容Lester Lobo 发布的帖子了解详细信息Have you tried to change the
TextOptions.TextFormattingMode
property toDisplay
? See this post from Lester Lobo for detailsFloele的回答指明了正确的方向,但答案并不完整。只需将 y 值设置为半个像素,例如 Y1="7" -> Y1="7.5"
这就是第二行和第三行不模糊的原因。
Floele's answer showed the right direction, but the answer was not complete. Just set the y-values to half a pixel, e.g. Y1="7" -> Y1="7.5"
That's the reason the second and third lines are not blurred.