ASP.NET TextRenderer.DrawText 可以生成糟糕的文本图像

7
自从我尝试使用Graphics.DrawString()的每个平滑和渲染组合来绘制字符串以来,我一直在思考文本渲染器是否能更好地绘制我的字符串,但我认为我是错误的。 这就是它应该看起来的样子: enter image description here 这就是它实际上的样子: enter image description here 以下是我的代码:
Graphics objGraphics2 = Graphics.FromImage(objBitmap);

objGraphics2.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
objGraphics2.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
objGraphics2.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
objGraphics2.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;

Font textFont = new Font(textFontFamily, PxtoEm(textSize));

SolidBrush b = new SolidBrush(textColor);

TextRenderer.DrawText(objGraphics2, textValue, textFont, new Rectangle(0, 0, Width, Height), textColor);

我的 PxtoEm 方法是否有问题?
public float PxtoEm(int px)
{
      float em = (float)(Convert.ToDouble(Convert.ToDouble(px) * Convert.ToDouble(72) / Convert.ToDouble(objBitmap.HorizontalResolution)));
      return em;
}

我需要一些建议,因为这真的很糟糕,在使用较大字体时会变得更糟,而图像不会缩小。
更新:使用更大的字体(即20px)可以工作,但是在某些字母上,使用较小的字体会有点被擦除:
这是使用Arial 10px字体时应该的样子:
如下所示:enter image description here 这是使用Graphics.DrawString()的结果:
如下所示:enter image description here 正如您所看到的,它确实不是很好,但是我最接近的。我对代码进行了一些更改,并使用较大字体获得了更好的结果:
这是使用Arial 20px字体时应该的样子:
如下所示:enter image description here 这是绘制结果:
如下所示:enter image description here 这是更改后的代码(我放弃了em方法并直接使用像素,改用Graphics.DrawString()而不是TextRenderer.DrawText())。
  Graphics objGraphics = Graphics.FromImage(objBitmap);
  objGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
  objGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
  objGraphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
  objGraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
  objGraphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
  Font textFont = new Font(textFontFamily, textSize,GraphicsUnit.Pixel);
  SolidBrush b = new SolidBrush(textColor);
  PointF origin = new PointF((float)TextLeft,(float)TextTop);
  StringFormat format = StringFormat.GenericTypographic;

  objGraphics.DrawString(textValue, textFont, b , origin, format);

如果有人对于较小文本大小的编写方法有建议,并且使用上述代码可以很好地处理较大文本,请发表意见,我会尝试!
更新3:最终找到了解决方案,而且解决方案相当简单:不要使用透明背景!
设置如下:
 objGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
 objGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; // <-- important!
 objGraphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
 objGraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
 objGraphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
          objGraphics.TextContrast = 0;

以下是使用这些设置在白色背景下的最终图像:

输入图片描述

完全相同,感谢建议和回复。


你正在用什么图形格式流传图像? - Bradley Uffner
格式为Png,背景透明。我目前正在尝试其他人建议的所有东西,到目前为止,当使用TextRenderer时没有任何变化,我又回到了Graphics.DrawString,并且结果稍微好了一些。当我找到正确的组合时,我会再次发布。 - formatc
很酷,只是检查一下,确保你没有尝试使用GIF,因为那样会丢失alpha通道并给你类似的丑陋结果。 - Bradley Uffner
4个回答

3

我不确定这是否有帮助,但为什么不像这样创建你的字体而不是使用函数调用:

 Font textFont = new Font(textFontFamily, textSize, GraphicsUnit.Pixel);

这确实有所帮助,但基本上还是一样的,不过还是谢谢你提醒我。 - formatc
没有想到这会对渲染质量有所帮助,但更简单的代码总是好的 :D - Hogan

2

我用类似的功能构建了一个生成图像按钮的工具,但是我在字距和字体未按预期宽度拉伸方面遇到了问题。以下设置让我接近了想要的效果,但仍不完美。

objGraphics2.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
objGraphics2.TextRenderingHint = System.Drawing.Drawing2D.TextRenderingHint.AntiAliasGridFit;

这个可以工作,但只适用于较大的字体(即20像素),无论如何,这是我迄今为止最接近的。我会尝试再做一些调整,看看是否能在较小的字体上获得更好的效果。 - formatc

2

Graphics.TextRenderingHint设置为SingleBitPerPixelGridFit


0

我不确定这是否能解决问题,但我在使用Direct3D绘制文本时遇到了类似的问题,请查看PixelOffsetMode,将其设置为Half


我尝试过,使用较大的字体会变得混乱,而在较小的字体上与HighQuality相同。 - formatc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接