【问题标题】:Creating an image with text and saving it as .png in C# using WPF使用 WPF 在 C# 中创建带有文本的图像并将其保存为 .png
【发布时间】:2016-12-01 02:59:49
【问题描述】:

我们正在开发一个光学字符识别系统,我想比较不同的渲染器如何渲染文本。我想制作一个简单的程序来创建一个图像,用不同的字体、大小和样式在上面写一些文本并将其保存到一个 .png 文件中(我想在一个文件中包含我需要的所有大小、字体样式,所以它们是容易比较)。我已经设法通过使用位图的 GDI 和 GDI+ 渲染器来做到这一点。 现在我正在尝试在 WPF 应用程序中做同样的事情,因为我听说渲染文本有不同。是否可以为此使用 BitmapImage ?来自 Windows 窗体,我认为这个问题应该很简单,但我似乎无法在 WPF 中完成。

这是我使用 GDI+ 渲染器的简化版本:

public void CreateAndSave()
{
    Bitmap bitmap = new Bitmap(500, 500, PixelFormat.Format24bppRgb);
    Graphics g = Graphics.FromImage(bitmap);
    g.Clear(Color.White);
    g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
    g.DrawString("sample text", font, brush, x, y);
    bitmap.Save(fileName);
}

WPF 有没有类似的方法?

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    诸如“DrawString”之类的方法在 WPF 中成本很高。而不是这样做,您可以创建一个画布/网格并放置文本框或标签等,然后您可以渲染该画布/网格。您可以使用该代码:

    public void ConvertToBitmapSource(UIElement element)
    {
        var target = new RenderTargetBitmap(
            (int)element.RenderSize.Width, (int)element.RenderSize.Height,
            96, 96, PixelFormats.Pbgra32);
        target.Render(element);
    
        var encoder = new PngBitmapEncoder();
        var outputFrame = BitmapFrame.Create(target);
        encoder.Frames.Add(outputFrame);
    
        using (var file = File.OpenWrite("TestImage.png"))
        {
            encoder.Save(file);
        }
    }
    

    【讨论】:

    • 感谢您的回答。这个想法可能会奏效。我现在遇到的问题是我想要一个有很多不同字体和大小的 .png,我必须创建很多标签才能做到这一点。此外,当我使用此方法时,.png 中呈现的文本与实际运行的应用程序上的文本不同。这可能是由于背景透明造成的。有没有一种快速的方法可以将 RenderTargetBitmap 的背景颜色设置为白色,还是我必须将每一位都设置为白色?
    • 如果您使用网格/画布作为 UIElement 的一种方法,请尝试将其背景设置为白色。它会工作
    • 我将背景更改为白色,但背景似乎并未导致文本质量不佳。也许如果它将整个元素渲染到 RenderTargetBitmap 上,它并不关心文本之前是如何渲染的。我也尝试在单个标签上使用此方法,但仍然没有这样做。
    • 所以文本质量也取决于分辨率和 dpi。您可以安排它们,但文件大小会更大
    • 我将 dpi 设置为 120 以匹配我的系统 dpi 并且它与原始的可接受地相似。谢谢你的帮助。
    【解决方案2】:

    使用 FormattedText 类构建一个 Geometry 对象,从这里举个例子: https://msdn.microsoft.com/en-us/library/system.windows.media.formattedtext.buildgeometry(v=vs.110).aspx

    然后,使用 BitmapEncoder 类之一来保存您构建的 Geometry 对象。看那个例子: https://stackoverflow.com/a/9081295/3730455

    【讨论】:

      猜你喜欢
      • 2020-10-12
      • 1970-01-01
      • 2017-08-13
      • 2014-09-14
      • 2014-05-01
      • 2013-03-26
      • 1970-01-01
      • 2012-10-04
      • 2013-01-29
      相关资源
      最近更新 更多