使用System.Drawing绘制文本时出现低分辨率图像

3
我正在尝试使用iTextSharp将图像写入PDF,除了写入图像之外,我还需要向PDF添加文本。似乎最好的方法是将文本作为图像编写并插入到页面上。这一切都很顺利,但当我查看文本时,发现它的质量不如我所希望的高。最终我得到了类似于这样的东西:

enter image description here

您可以看到有很多与周围实体背景不同的“点”。这是我用来绘制文本的代码:

private System.Drawing.Image DrawText(String text, System.Drawing.Font font, Color textColor, Color backColor)
    {
        Bitmap img = new Bitmap(1, 1);
        Graphics drawing = Graphics.FromImage(img);

        SizeF textSize = drawing.MeasureString(text, font);

        img.Dispose();
        drawing.Dispose();

        img = new Bitmap((int) textSize.Width, (int) textSize.Height);
        //img.SetResolution(200, 200);

        drawing = Graphics.FromImage(img);

        drawing.Clear(backColor);

        Brush textBrush = new SolidBrush(textColor);

        drawing.DrawString(text, font, textBrush, 0, 0);
        //drawing.TextRenderingHint = TextRenderingHint.AntiAlias;
        //drawing.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
        //drawing.SmoothingMode = SmoothingMode.HighQuality;

        //img.MakeTransparent(Color.MediumAquamarine);

        drawing.Save();

        textBrush.Dispose();
        drawing.Dispose();

        return img;
    }

和PDF编写器相关的文本:

    var name = DrawText(Request.Form["name"], font, Color.Black, Color.White);
    ...
    Image titleImg = Image.GetInstance(title.ToStream(ImageFormat.Jpeg));
    titleImg.SetAbsolutePosition(float.Parse(Request.Form["x"]), float.Parse(Request.Form["y"]));
    titleImg.ScaleToFit(16, 16);           
    pdfContentByte.AddImage(titleImg);

我不确定这是iTextSharp的ScaleToFit()还是绘图方法的问题,但我想稍微清理一下背景颜色。您可以在DrawText()方法的注释中看到我尝试过的各种方法。

非常感谢您的帮助!


2
如果我是你,我不会首先将文本绘制为位图,而是使用PDF文本显示操作符,从而允许写作的任意平滑度。 - mkl
1
@mkl你是什么意思?你有一个使用你上面提到的方法的例子吗?当我尝试向PDF添加文本时,它并没有像我希望的那样顺利...它只是创建了新页面,而不是在我需要的位置附加,这些位置基本上是文档中的标记。 - awh112
2个回答

5
您尝试的文本呈现提示和平滑模式值实际上是适得其反的。如果您不想要文本周围的抗锯齿像素,请将它们关闭!设置文本呈现提示为单色半调格栅拟合或单色半调应该更好地工作。
但是即使使用,如果您没有保存为 jpeg ,则像素化也肯定不会那么强烈,这可能是唯一的真正错误。
每当涉及到文本时,请不要使用 jpeg ,因为它严格用于照片,而是使用< PNG> png !
所以首先更改
Image titleImg = Image.GetInstance(title.ToStream(ImageFormat.Jpeg));

to

Image titleImg = Image.GetInstance(title.ToStream(ImageFormat.Png));

仅在这之后再检查是否要优化TextRenderingHint

注意:本答案仅涉及消除文字周围的伪影。

PFD文档中输入文本的最佳可扩展方法是输入真实文本,而不是位图,正如mkl所评论的那样。如何在ITextSharp中以及在您的应用程序环境中这样做是一个很好的新问题,您可能需要发布(请包括您失败的尝试和期望结果的图像..!)


将文件格式从JPEG改为PNG就解决了问题,我根本不需要改变TextRenderingHint。非常感谢! - awh112

0

我使用了你的代码,效果非常好。

我整理了将其分成两个(2)独立方法的方法,然后我从一个更大的位图开始(而不是1x1):

using System;
using System.Drawing;

class Program
{

    public static Color COLOR_TEXT = Color.Red;
    public static Color COLOR_BACK = Color.White;

    static void Main(string[] args)
    {
        var font = new Font(FontFamily.GenericMonospace, 35);
        var image = DrawClass.DrawText2("Stack Overflow\r\n\tby jp2code", font, COLOR_TEXT, COLOR_BACK);
        image.Save("C:\\jp2code.bmp");
    }

    public static Image DrawText2(String text, Font font, Color textColor, Color backColor)
    {
        var textSize = GetTextSize(text, font);
        var result = new Bitmap((int)textSize.Width, (int)textSize.Height);
        using (var g = Graphics.FromImage(result))
        {
            g.Clear(backColor);
            var brush = new SolidBrush(textColor);
            g.DrawString(text, font, brush, 0, 0);
            g.Save();
        }
        return result;
    }

    public static SizeF GetTextSize(String text, Font font)
    {
        using (var img = new Bitmap(200, 100))
        {
            using (var g = Graphics.FromImage(img))
            {
                return g.MeasureString(text, font);
            }
        }
    }

}

这是我的输出文件:

screenshot

很不错。那就是几小时前我给你点赞的理由。

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