c# - 在 .NET 2.0 上消除文本锯齿的更好方法吗?

标签 c# .net winforms fonts

我想像这张截图一样消除锯齿:

enter image description here

我已经尝试了所有的 TextRenderingHints,但它看起来仍然很糟糕。 请注意,当我制作屏幕截图时,PNG 使其更平滑,但您仍然可以看到第二个文本不如第一个文本好。 这是我的代码:

private void Form1_Paint(object sender, PaintEventArgs e) {
    try {
        SolidBrush solidBrush = new SolidBrush(Color.Black);
        PrivateFontCollection fonts;
        FontFamily family = LoadFontFamily(Properties.Resources.SegoeWP_Light, out fonts);
        Font font = new Font(family, 18);
        e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
        e.Graphics.TextRenderingHint = TextRenderingHint.SystemDefault;
        e.Graphics.DrawString("Downloads", font, solidBrush, new PointF(135, 80));
    } catch (Exception ex) {
        MessageBox.Show(ex.ToString());
    }
}

是否有其他方法可以在 WinForms (.NET 2.0) 上平滑字体?

最佳答案

我相信 Photoshop 会过采样。您可能无法获得与 Photoshop 一样好的结果——它有更好的像素捕捉算法,并且它可能会做一些事情,比如稍微增加轮廓以获得更暗的结果——但如果 SmoothingMode.AntiAlias (as George suggested) 是不够的,你可以尝试这些步骤看看他们是否得到你想要的结果。

  1. 创建一个新的 Font,其大小是您最终想要的大小的两倍。
  2. 使用较大的字体测量文本,并创建该大小的位图。确保使用支持 alpha 透明度的格式创建它。
  3. 将文本绘制到您的 Bitmap(在 (0, 0) 处)。 (您可能想在此处使用 SmoothingMode.AntiAlias。)
  4. Bitmap 绘制到您的最终目标,将其缩小 50%。确保使用高质量的大小调整模式。

这将从您的示例图像中获得更多“平滑”效果,因为您基本上是在绘制子像素网格。不过,您的结果可能会有所不同——您可能需要在 (0, 1) 而不是 (0, 0) 处绘制以使其看起来足够清晰,并且您可能需要调整字体大小。您甚至可以尝试以 3 倍而不是 2 倍的比例进行绘制,但如果超出这个比例,您将不会获得太多好处。

最大的问题是您的文本可能不够暗——如果以 2x 大小绘制 1 像素宽的线条,那么在最终结果中它们将只有 50% 是黑色。解决这个问题的最好方法是选择线条较粗的字体。您还可以尝试 overdraw Bitmap 中的文本 - 在 (0, 0) 处绘制一次,然后在 (0, 1) 或 (1,0) 处再次绘制 - 看看它是否变厚一旦你缩小尺寸,这些线条就足够好看了。您必须进行试验。

我不建议将此用于通用文本绘制(用户选择布局和字体大小),但如果您可以完全控制字体大小,则可以调整它以获得很好的效果结果。

关于c# - 在 .NET 2.0 上消除文本锯齿的更好方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8259898/

相关文章:

c# - 通过线程池内的定时器执行方法

c# - jQuery 是在 C#.net 环境中处理用户交互的最佳方式吗?

c# - 使用 IBindingList 在 WinForms 中进行数据绑定(bind)在空列表上失败

c# - 如何在winform的标题栏中包含帮助 '?'

c# - 使用 Entity Framework 查询许多(~100)个搜索词

c# - 关于C# Expression.MakeBinary(),使用方法

c# performance : type comparison vs. 字符串比较

c# - UtcNow 返回有缺陷的时间戳

c# - 在 C# 2.0+ 中,是否有必要锁定另一个线程将执行的闭包?

c# - DataGridView 单元格中的多行文本