WPF中的模糊文本,即使启用了ClearTypeHinting?

时间:2012-04-15 10:26:18

标签: c# .net wpf xaml cleartype

我在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,似乎会使文字渲染模糊(灰色抗锯齿):

enter image description here

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

enter image description here

我已尝试将RenderOptions.ClearTypeHint="Enabled"应用于ContentPresenter,如上所示,但它无济于事。

如何强制WPF渲染使用投影效果显示的文本以保留Cleartype抗锯齿,而不是那种难看的模糊灰色子像素消除锯齿?

有些人认为它因为投影而变得模糊 - 这不是真的。它只是模糊,因为没有使用ClearType。当阴影和ClearType:

时,这就是它在Firefox中的样子

enter image description here

启用ClearType的文字很丰富 - 但是模糊的文字不是,因为它不使用ClearType - 它使用灰色子像素消除锯齿,而不是ClearType的工作方式:http://en.wikipedia.org/wiki/ClearType

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

6 个答案:

答案 0 :(得分:12)

如何将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>

下面是它的样子。

enter image description here

这就是它在FireFox中的样子。

enter image description here

答案 1 :(得分:4)

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

  

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

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

答案 2 :(得分: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>

这产生了期望的结果:

enter image description here

enter image description here

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

答案 3 :(得分:3)

如何将这两个想法结合起来。使用DropShadowEffect绘制文本,并使用相同的文本覆盖它而不会产生效果,如第三行所示:

text

仍然不完美,我发现它有点大胆。但也许你可以忍受的东西。 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>

答案 4 :(得分:2)

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

理解这一点的下一步是WPF效果首先渲染到屏幕外的位图,然后与下面的内容组合在一起(在这种情况下,如果选择了纯白色,或者可能是蓝色)。

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

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

答案 5 :(得分:1)

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

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