【问题标题】:Blurry text in WPF even with ClearTypeHinting enabled?即使启用了 ClearTypeHinting,WPF 中的文本也会变得模糊?
【发布时间】:2012-04-27 00:28:48
【问题描述】:

我在 WPF/XAML 中有一个带有此模板和样式的网格:

<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
<Setter Property="RenderOptions.ClearTypeHint" Value="Enabled" />
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type DataGridCell}">
            <Border Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                <ContentPresenter x:Name="CellContent" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RenderOptions.ClearTypeHint="Enabled" />
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter TargetName="CellContent" Property="TextOptions.TextFormattingMode" Value="Display" />
                    <Setter TargetName="CellContent" Property="RenderOptions.ClearTypeHint" Value="Enabled" />
                    <Setter TargetName="CellContent" Property="Effect">
                        <Setter.Value>
                            <DropShadowEffect ShadowDepth="2" BlurRadius="2" Color="Black" RenderingBias="Quality" />
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Setter.Value>
</Setter>

我的DropShadowEffect当你选择一个网格行时,似乎使文本渲染模糊(灰色抗锯齿):

当我移除投影效果时,它看起来很清晰,因为它现在使用 ClearType 而不是灰色亚像素抗锯齿:

我已尝试将RenderOptions.ClearTypeHint="Enabled" 应用于ContentPresenter,如上所示,但没有帮助。

如何强制 WPF 呈现以投影效果显示的文本以保留 Cleartype 抗锯齿,而不是那种丑陋的模糊灰色亚像素抗锯齿?

有些人认为由于投影而模糊 - 这不是真的。只是因为没有使用 ClearType 才模糊。这是阴影和 ClearType 在 Firefox 中的样子:

启用 ClearType 的文本是彩色的 - 但模糊文本不是,因为它不使用 ClearType - 它使用灰色亚像素抗锯齿,这不是 ClearType 的工作原理:http://en.wikipedia.org/wiki/ClearType

问题是:如何为这个文本启用 ClearType?

【问题讨论】:

  • 在我看来,它看起来很模糊是因为阴影效果,而不是因为抗锯齿样式。
  • @CodyGray 对不起,你错了。 :) 很模糊,因为没有使用 ClearType。
  • 嗯...你能告诉我我的回答有什么问题吗?
  • Pedantry:我想指出,文本阴影渲染只是标准的抗锯齿,就像在 Mac 和 Linux 操作系统上使用的那样。它没有任何“亚像素”。 ClearType 的特别之处(如此丰富多彩)在于它使用亚像素渲染。

标签: c# .net wpf xaml cleartype


【解决方案1】:

TextOptions.TextFormattingMode 设置为Display 以及将RenderOptions.BitmapScalingMode 设置为NearestNeighbor 怎么样?后者是 WPF 3.5 SP1 中的新功能,我通常使用它来消除模糊。 :)

<TextBlock Text="Hello world" TextOptions.TextFormattingMode="Display"
           RenderOptions.BitmapScalingMode="NearestNeighbor"
           HorizontalAlignment="Center" TextWrapping="Wrap"
           VerticalAlignment="Center" Foreground="White" FontFamily="Microsoft Sans Serif">
    <TextBlock.Effect>
        <DropShadowEffect ShadowDepth="2" BlurRadius="2" Color="Black"
                          RenderingBias="Quality"/>
    </TextBlock.Effect>
</TextBlock>

下面是它的样子。

这就是它在 FireFox 中的样子。

【讨论】:

  • 仍然有些模糊,虽然更好。我得出的结论是没有解决办法。变通办法看起来会稍微好一些或更糟,具体取决于显示器,也可能还有其他因素。
  • 真的吗?从上面的截图来看,第一个在我看来非常清晰......我什至尝试了几台显示器(好的和坏的),它们看起来都很清晰......
  • 这是它的样子(直接复制和粘贴后):d.pr/i/29CC 在您的屏幕截图和我的屏幕截图中,ClearType 未激活。出于某种原因,在您的计算机上,ClearType-less 会产生更好的质量。在我的电脑上 any ClearType-less 文本很乱。然而 Firefox 使用 ClearType 并且一切看起来都很清晰。我选择了“不可能”的答案,因为我得出的结论是 WPF 4 不可能。我希望这会有所改变。
  • 这是一个截图:d.pr/i/QXsL(我移除效果后,奇怪的模糊性就消失了)。
  • 我刚刚注意到的一件事是,实际上是这个TextOptions.TextRenderingMode="ClearType" 给出了文本ClearType,但我猜你可能已经尝试过这个了?我发现的另一件事是,我的表情混合设计器视图中的TextBlock 看起来有点模糊,就像你的屏幕截图一样,但是当我运行应用程序时它看起来很好。我想知道这可能是计算机设置问题吗?
【解决方案2】:

DropShadowEffect 对象不能与 ClearType 一起使用。这在 MSDN 页面How to: Create Text with a Shadow 上有说明:

这些阴影效果不会通过 Windows 演示文稿 Foundation (WPF) 文本渲染管道。结果,ClearType 是 使用这些效果时禁用。

毕竟DropShadowEffect是位图效果,不是文字效果。

【讨论】:

  • 那么,你是说我无法在WPF中实现文字阴影之类的简单事情吗?我们在 Web 浏览器中使用 CSS text-shadow: 1px 1px 1px #000 的东西?你确定没有办法解决这个问题吗?
  • @rFactor:我不知道在 WPF 中产生文本阴影的任何替代方法。但其他人可能会。 Firefox 可能已经实现了专门为 HTML 和 CSS 定制的图形引擎。他们可以通过首先在文本上使用模糊位图效果绘制阴影,然后在启用 ClearType 的情况下第二次绘制文本来实现该效果。
  • @rFactor:这里可能的解决方法是渲染文本两次,一次是黑色,另一次稍微偏移。
  • @KentBoogaart 这到底是怎么回事?如果可行,我会给你一个温暖的拥抱。
  • 有人试过用TranslateTransform 代替吗?这有点麻烦,但它可能会奏效。
【解决方案3】:

要在不使用效果的情况下达到类似的效果,您可以渲染文本两次,一次稍微偏移另一次:

<Grid>
    <TextBlock Text="Here is some sample text" Foreground="Black" Margin="1,1,0,0"/>
    <TextBlock Text="Here is some sample text" Foreground="White"/>
</Grid>

这会产生预期的结果:

您也可以将其封装到一个控件中(也许称为ShadowTextBlock),这样您就不必到处重复自己了。

【讨论】:

  • 我觉得它看起来有点锯齿,有什么方法可以让它变得又脆又光滑?你如何使用ContentPresenter 来做到这一点,因为你不能“复制”它?
  • @rFactor:尝试使用颜色。灰色而不是黑色会降低对比度。
  • 无论我如何尝试调整它,它总是看起来很糟糕。这是一个看起来有多好的例子(试试 Firefox):jsfiddle.net/kaisellgren/2YEer/1
【解决方案4】:

如何结合这两个想法。用 DropShadowEffect 绘制文本,并用绘制的没有效果的相同文本覆盖它,如这里的第三行所示:

仍然不完美,我觉得它有点大胆。但也许你可以忍受的东西。 XAML:

<StackPanel Background="LightSteelBlue" RenderOptions.ClearTypeHint="Enabled" SnapsToDevicePixels="True" >
    <Grid Margin="5">
        <TextBlock Foreground="Black" Text="Here is some sample text" Margin="1"/>
        <TextBlock Foreground="White" Text="Here is some sample text"/>
    </Grid>
    <TextBlock Margin="5" Foreground="White" Text="Here is some sample text">
        <TextBlock.Effect>
            <DropShadowEffect ShadowDepth="2" BlurRadius="2" Color="Black" RenderingBias="Quality"/>
        </TextBlock.Effect>
    </TextBlock>
    <Grid Margin="5">
        <TextBlock Foreground="White" Text="Here is some sample text">
            <TextBlock.Effect>
                <DropShadowEffect ShadowDepth="2" BlurRadius="2" Color="Black" RenderingBias="Quality"/>
            </TextBlock.Effect>
        </TextBlock>
        <TextBlock Foreground="White" Text="Here is some sample text"/>
    </Grid>
</StackPanel>

【讨论】:

    【解决方案5】:

    这不起作用的原因,以及您无法让它工作的原因,都与 ClearType 对它所呈现的内容的敏感性有关。为了让 ClearType 看起来正确,它本质上需要进行每个组件的 alpha 混合。也就是说,红色、绿色和蓝色的单独 alpha 值(通常 alpha 适用于所有 3 个)。这意味着 ClearType 绝对必须被渲染成一个已经不透明的位图(所有 alpha 值都是 255)(你会注意到窗口标题栏仍然有 ClearType,但是他们使用了一些超级秘密技巧来做到这一点)。

    理解这一点的下一步是 WPF 效果首先呈现为屏幕外位图,然后与下方的内容组合(在本例中为纯白色,或者如果选中,则可能为蓝色)。

    因此,首先将文本呈现为清晰、透明的位图。因为它不知道最终会在它下面是什么,所以它必须使用灰度而不是 ClearType 进行渲染。然后,效果将应用于该位图。然后将位图绘制到您希望它在屏幕上的位置,即使它位于没有透明度的纯色之上,也没有机会获得 ClearType。

    作为一种可能的解决方法,请尝试使用 2 个文本副本。首先,将效果应用于文本的“较低”版本(“较低”是指它应该具有较低的 Z-index 值,如果它在 XAML 中是“第一个”则就是这种情况)。然后,在其上绘制普通文本(将获得 ClearType)。我认为这会起作用,但我还没有尝试过,您可能需要进行试验,直到获得所需的视觉效果。

    【讨论】:

    • 所以我想这可以解释为什么即使是带有阴影的Border 对象也会“中断”文本。虽然并不总是很奇怪
    【解决方案6】:

    我知道这篇文章很旧,但如果有人遇到模糊文本的问题,那么边框阴影可能是罪魁祸首。我有带有阴影的自定义面板,只有当面板并排放置时,文本才会模糊。我从这个Why everything in WPF is blurry? 帖子中找到了答案。对我来说,解决方案是 ecreif 的答案,而不是公认的答案。将此添加到您的控件中

        UseLayoutRounding="True"
        RenderOptions.BitmapScalingMode="NearestNeighbor"
        SnapsToDevicePixels="True
        RenderOptions.ClearTypeHint="Enabled"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-04
      • 1970-01-01
      • 2022-12-06
      • 1970-01-01
      • 2016-04-15
      • 1970-01-01
      • 2015-05-05
      • 2023-03-22
      相关资源
      最近更新 更多