WPF模糊字体问题-解决方案


153

在以下链接上描述和演示了问题:

说明:WPF中的文本清晰度。此链接具有字体比较。

我想收集所有可能的解决方案。Microsoft Expression Blend使用WPF,但是字体看起来可读。

  • 如Microsoft Expression Blend中的深色背景
  • 增加字体大小并更改字体(Calibri ...)[链接]
  • 嵌入Windows表单[链接]
  • 使用GDI +和/或Windows Forms TextRenderer类将文本呈现为位图,然后将该位图呈现为WPF控件。[链接]

还有其他解决方案吗?

这将在VS2010(和WPF4)测试版2中修复

它看起来像已经解决了!

Scott Hanselman的ComputerZen.com:WPF和文本模糊,现在完全清晰



我的机器上的VS2010RC看上去比您的图片要好得多,实际上白色背景非常好,但是深色背景仍然很烂。
罗伯特·武科维奇(RobertVuković)2010年

您是否找到了解决此问题的任何方法,实际上我的应用程序中遇到了同样的问题,并且我在VS2010中使用WPF 3.5
SharpUrBrain 2011年

最后3个链接已失效。
SHIN JaeGuk

Answers:


107

技术背景

在Windowsclient.net上有一篇有关WPF文本渲染的深入文章,来自一个WPF文本程序管理器:WPF中的文本清晰度

问题归结为WPF,需要线性缩放的字体渲染器来平滑动画。另一方面,Pure ClearType在字体方面具有相当大的自由度,可将垂直词干推入下一个像素。

如果人们比较经典的“层叠”模式,则差异是显而易见的。WinForms位于左下方,WPF位于右上方:

虽然我也不喜欢WPF的字体渲染特质,但我可以想象一下,如果动画像Winforms级联中那样跳跃,就会大声疾呼。

玩注册表

我特别感兴趣的是MSDN文章“ ClearType注册表设置 ” 的链接,该文章解释了注册表中用户端的可能调整:

  • ClearType级别:子像素提示量
  • 伽玛水平
  • 像素结构:显示像素中的颜色条纹如何排列
  • 文本对比度:调整字形茎的宽度以使字体更重

使用这些设置并不能真正改善根本问题,但可以通过减少敏感用户的色斑效应来提供帮助。

另一种方法

Text Clarity文章提供的最佳建议是增加字体大小和更改字体。Calibri对我来说比标准Segoe UI更好。由于它作为Web字体的流行性,我也尝试了Verdana,但是它在14pt和15pt之间的重量变化很大,在设置字体大小的动画时非常明显。

WPF 4.0

WPF 4将改进对影响字体渲染的支持。WPF文本博客上一篇文章介绍了所做的更改。最突出的是,现在(至少)存在三种不同类型的文本呈现:

文字渲染比较

<grumble>对于每个设计师来说,这应该足够了。</ grumble>


11
很好的解释,+ 1。大概可以解释为什么Flash也具有如此恐怖的字体渲染。
杰夫·阿特伍德

1
是。这是一个很好的解释,但是我仍然希望有一种方法可以在您不打算进行动画处理时打开字体提示以使外观漂亮。我想这将暗示您正在优化提示的给定比例。这种东西使WPF在我看来仍然是beta版。
PeterAllenWebb

这不像“可伸缩”变体不使用字体提示,只是WPF不能像ClearType那样针对击中像素网格进行优化。可以说SnapToDevicePixels应该适用于文本,但这总是必须被继承,因为控件无法知道它是否可以对齐。
David Schmitt,

2
特别相关的是TextOptions.TextFormattingMode附加属性(msdn.microsoft.com/en-us/library/ee169597.aspx)。WPF4和Silverlight还具有UseLayoutRounding(msdn.microsoft.com/en-us/library/dd783605.aspx)和SnapsToDevicePixels(msdn.microsoft.com/en-us/library/…)属性。
帕特

@All:我找不到在WPF3.5中禁用文本抗锯齿的方法,结果标签或按钮文本看起来真的很糟糕。理想情况下,我想全局禁用字体的抗锯齿功能。我该怎么做?
SharpUrBrain

128

.NET 4终于可以解决WPF较差的文本呈现质量,但是它是隐藏的。为每个窗口设置以下内容:

TextOptions.TextFormattingMode="Display"

默认值为“理想”,这与名称所暗示的完全不同。

TextOptions中还有两个其他选项,分别为TextHintingMode和TextRenderingMode,但是它们都有合理的默认值。


所有。谢谢。这可以帮助我解决问题,但是您只需在容器中定义一次,例如<grid>
Peter Du

是的,如果将其设置在窗口中,则该窗口对该窗口中包含的所有内容均有效。
Helge Klein

花了很多时间在大量站点和博客上寻找这些内容,并且不断地探讨VS2010 RTM / .Net 4中文本格式的改进程度(我同意,是的!)。但是他们都不在乎如何使用它来构建WPF应用程序,看起来也不错。为什么该物业如此隐秘?非常感谢你。
M-Peror 2012年

5
我想要的就是这个!我真的不在乎WPF呈现的复杂程度,字体对任何人都是不可接受的。
杰瑞·梁

1
“理想”对我有效,而不是“展示”。该项目位于.NET 4.6.2上。也许他们解决了混淆的名称。

40

前几天,当我使用应用了DropShadowEffect的边框时遇到了一个问题。结果是该边框内的所有文本都非常模糊。文本是在其他面板内部还是在边框的正下方都没有关系- 应用于父级的子级文本块如果应用了“ 效果”,似乎都将受到影响。

解决这种特殊情况的方法是,不要将东西放在有效果的边框内,而应使用网格(或支持将内容彼此叠加的其他任何东西),并在与文本相同的单元格中放置一个矩形(即作为视觉树中的兄弟姐妹),并在其上放置效果。

像这样:

<!-- don't do this --->
<Border>
     <Border.Effect>
          <DropShadowEffect BlurRadius="25" ShadowDepth="0" Opacity="1"/>
     </Border.Effect>
     <TextBlock Text="This Text Will Be Blurry" />
</Border>

<!-- Do this instead -->
<Grid>
  <Rectangle>
     <Rectangle.Effect>
          <DropShadowEffect BlurRadius="25" ShadowDepth="0" Opacity="1"/>
     </Rectangle.Effect>
  </Rectangle>
  <TextBlock Text="This Text Will Be Crisp and Clear" />
</Grid>

这很好地完成了这个技巧。有点破解,但是总比弄乱设置等好。谢谢。但是,我要做的一件事是将矩形的填充设置为某种值。也许这只是我的设置。
哈德斯2010年

是的,您是对的。默认情况下,矩形是透明的,这使阴影看起来很奇怪。
Isak Savo

这在我的示例应用程序中没有发生,我正在使用WPF 3.5
SharpUrBrain 2011年

@SharpUrBrain:怎么了?即使使用第二个示例,它仍然模糊吗?
Isak Savo

是的,在也使用了第二个示例之后,它仍然很模糊
SharpUrBrain 2011年


6

SnapToDevicePixels仅适用于WPF形状(线条等),不适用于文本渲染器。

没有解决此问题的已知方法。根据Microsoft的说法,此行为是“设计使然”。

另请参阅微软论坛中讨论的问题线程-它从MS球员这阐明他们对这一问题的立场得到一些回复。


在WPF 4中使用TextOptions.TextFormattingMode附加属性(msdn.microsoft.com/en-us/library/ee169597.aspx)已修复。
帕特

1
属性名称为“ SnapsToDevicePixels”,而不是书面形式的“ SnapToDevicePixels”。
尼尔·科恩菲尔德

6

从开发人员的角度来看,迄今为止唯一已知的“解决方法”是使用GDI +和/或Windows Forms TextRenderer类将文本呈现为位图,然后将该位图呈现为WPF控件。除了明显的性能影响外,这不能缓解现有应用程序的问题。

我现在已针对此问题创建了一个Microsoft Connect票证(令我惊讶的是,尽管存在很多负面影响,但指定的跟踪器中没有实际的错误报告)。

由于这是向Microsoft传达请求和问题的官方渠道之一,因此我建议您也仔细阅读一下,以获取更快的答案。至少,如果您希望以一种或另一种方式解决问题,则在那里投票表决和/或验证问题将有助于引起Microsoft PM和工程师对该问题的关注,并可能提高其优先级。


6

我不认为这是一个错误,但是默认配置确实很烦人。这是所有组合的比较

TextOptions.TextRenderingMode
TextOptions.TextFormattingMode
RenderOptions.ClearTypeHint

SnapToDevicePixels 在文本呈现方面没有任何区别。

http://i.stack.imgur.com/cS3S2.png

我更喜欢:

TextOptions.TextRenderingMode="Auto"
TextOptions.TextFormattingMode="Ideal"
RenderOptions.ClearTypeHint="Auto"

垂直线从不模糊。

使用的字体是Open Sans Light,如果使用得当,它可以非常漂亮,例如最新的TeamViewer。

对于使用Mahapps.Metro的用户来说,问题是TransitioningContentControl https://github.com/MahApps/MahApps.Metro/issues/889


4

刚刚试用了VS2010 beta,这些都是在WPF中完成的,而且字体模糊问题使BADLY深受其害。特别是在工具提示上。

这似乎提供了一些证据,证明WPF4实际上无法解决问题(如果看起来更糟)


3
我在VS2010B1中针对用户界面中每个位置的文本都模糊不清提交了bug。我同意,工具提示几乎是可笑的。鉴于有明确的说法将在WPF4中修复,因此我只能希望它不会降低该Beta的成本。
Will Dean

4

哇,我简直不敢相信我的WPF字体终于可读了。而且我也无法相信没有选项对话框可以使这些更改变得容易,而默认值在我的显示器上却很可怕。

这些注册表设置(十进制)对我有用,并且最接近我的常规cleartype字体:

  • ClearTypeLevel:10(主要是灰度别名)
  • GammaLevel:1300(较高的Gamma会使字体太细,并且我看到混叠中的颜色)

3

他们说“ SnapToDevicePixels = true”有效,但我从未见过任何好的结果。

我通过切换到其他字体来处理模糊文本。

显然,这不是解决问题的方法,但是这就是我的解决方法。


我只是比较了一个带有SnapToDevicePixels =“ true”的TextBlock和不带有SnapToDevicePixels =“ true”的TextBlock,并且与12duis 的Segoe UI字体没有区别。请问您使用什么字体?
David Schmitt,

我们还通过切换字体使情况更好。我们选择的字体是Avenir(我不认为它是默认安装的,至少不是在Windows XP上安装的)。
cplotts

0

如果您更喜欢使用C#基类为应用程序自定义窗口(或现在有理由这样做),则可以通过以下方法设置文本格式以使用吸引人的显示模式:

public class SnappyWindow : Window
{
    public SnappyWindow()
    {
        SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.