【问题标题】:Different Text Rendering Methods Don't Produce The One I Want不同的文本渲染方法不会产生我想要的
【发布时间】:2013-07-15 00:05:24
【问题描述】:

我正在寻找一种文本渲染方法,其中从位图初始化图形对象,在其上绘制文本,并且文本看起来像附加图像中的第一行。

有人可以解释一下可以做到这一点的方法吗?我不完全理解为什么以下方法都不能重现它:

测试字体为:Segoe UI,8.25pt

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
    base.OnPaint(e);

    //drawing the string with the Graphics object the form gives us
    e.Graphics.DrawString("1. This is a test using DrawString. " + e.Graphics.TextRenderingHint.ToString(), 
                          base.Font, Brushes.Black, new Point(10, 10));

    //width used for all images
    const int width = 300;

    //drawing the string with Graphics objects initialized from bitmaps
    Bitmap bmp = new Bitmap(width, 20);
    using (Graphics gfx = Graphics.FromImage(bmp))
    {
        gfx.PageUnit = GraphicsUnit.Pixel;
        gfx.SmoothingMode = SmoothingMode.HighQuality;
        gfx.DrawString("2. This is a test using DrawString. " + gfx.TextRenderingHint.ToString(), 
                       base.Font, Brushes.Black, Point.Empty);
    }
    e.Graphics.DrawImage(bmp, new Point(10, 30));

    bmp.Dispose();
    bmp = new Bitmap(width, 20);

    using (Graphics gfx = Graphics.FromImage(bmp))
    {
        gfx.PageUnit = GraphicsUnit.Pixel;
        gfx.SmoothingMode = SmoothingMode.HighQuality;
        gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
        gfx.DrawString("3. This is a test using DrawString. " + gfx.TextRenderingHint.ToString(), 
                       base.Font, Brushes.Black, Point.Empty);
    }

    e.Graphics.DrawImage(bmp, new Point(10, 50));

    bmp.Dispose();
    bmp = new Bitmap(width, 20);

    using (Graphics gfx = Graphics.FromImage(bmp))
    {
        gfx.PageUnit = GraphicsUnit.Pixel;
        gfx.SmoothingMode = SmoothingMode.HighQuality;
        gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
        gfx.DrawString("4. This is a test using DrawString. " + gfx.TextRenderingHint.ToString(), 
                       base.Font, Brushes.Black, Point.Empty);
    }

    e.Graphics.DrawImage(bmp, new Point(10, 70));

    bmp.Dispose();
    bmp = new Bitmap(width, 20);

    using (Graphics gfx = Graphics.FromImage(bmp))
    {
        gfx.PageUnit = GraphicsUnit.Pixel;
        gfx.SmoothingMode = SmoothingMode.HighQuality;
        gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
        gfx.DrawString("5. This is a test using DrawString. " + gfx.TextRenderingHint.ToString(),
                       base.Font, Brushes.Black, Point.Empty);
    }

    e.Graphics.DrawImage(bmp, new Point(10, 90));

    bmp.Dispose();
    bmp = new Bitmap(width, 20);

    using (Graphics gfx = Graphics.FromImage(bmp))
    {
        gfx.PageUnit = GraphicsUnit.Pixel;
        gfx.SmoothingMode = SmoothingMode.HighQuality;
        using (GraphicsPath path = new GraphicsPath())
        {
            path.AddString("6. This is a test using GraphicsPath. " + gfx.TextRenderingHint.ToString(), 
                           base.Font.FontFamily, (int)base.Font.Style, 
                           base.Font.Size, Point.Empty, StringFormat.GenericDefault);

            gfx.FillPath(Brushes.Black, path);
        }
    }

    e.Graphics.DrawImage(bmp, new Point(10, 110));

    bmp.Dispose();
    bmp = new Bitmap(width, 20);

    using (Graphics gfx = Graphics.FromImage(bmp))
    {
        gfx.PageUnit = GraphicsUnit.Pixel;
        gfx.SmoothingMode = SmoothingMode.HighQuality;
        gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
        using (GraphicsPath path = new GraphicsPath())
        {
            path.AddString("7. This is a test using GraphicsPath. " + gfx.TextRenderingHint.ToString(),
                           base.Font.FontFamily, (int)base.Font.Style,
                           base.Font.Size, Point.Empty, StringFormat.GenericDefault);

            gfx.FillPath(Brushes.Black, path);
        }
    }

    e.Graphics.DrawImage(bmp, new Point(10, 130));

}

【问题讨论】:

  • 你试过TextRenderingHint.ClearTypeGridFit吗?编辑:如果您使用“测试 4”版本但使用 TextRenderingHint.SystemDefault 会发生什么?
  • +1 好问题 我以前也遇到过这个问题,但没有提出问题
  • @ChrisSinclair ClearTypeGridFit 看起来也不像它。 SystemDefault 是图形对象初始化时的默认值,类似于#2。
  • 您是否尝试过检查所有传入e.Graphics对象的属性(例如它的PageUnitSmoothingModeTextContrastInterpolationMode等,看看哪些值与您从Graphics.FromImage(bmp) 获得的Graphics 对象不同?
  • @ChrisSinclair 是的,唯一不同的是PageUnit属性(FromImage初始化为Display,Form传递Pixel)。其他一切都是一样的。这就是我在每个测试用例中设置 PageUnit 属性的原因。

标签: c# .net gdi+ gdi


【解决方案1】:

您的代码中存在错误,您忘记初始化位图。它将填充 Color.Transparent、黑色、alpha 为 0 的像素。当您绘制文本时,Graphics.DrawString() 将实现您要求的 TextRenderingHint,对文本进行抗锯齿处理。但是文本的前景色是黑色的。并且背景颜色是黑色。所以抗锯齿像素从黑色混合到黑色。完全破坏了抗锯齿效果,它将字母形状变成了一个斑点。修复:

Bitmap bmp = new Bitmap(width, 20);
using (Graphics gfx = Graphics.FromImage(bmp))
{
    gfx.Clear(this.BackColor);
    // etc...
}

【讨论】:

  • 确实是问题所在。谢谢你,汉斯。
猜你喜欢
  • 2016-05-26
  • 2018-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-02
  • 2016-07-29
  • 1970-01-01
相关资源
最近更新 更多