如何在运行时即时从文本生成图像

Posted

技术标签:

【中文标题】如何在运行时即时从文本生成图像【英文标题】:How to generate an image from text on fly at runtime 【发布时间】:2011-01-05 10:27:49 【问题描述】:

任何人都可以指导如何从输入文本生成图像。图片可能有任何扩展名都没有关系。

【问题讨论】:

您的意思是像您从屏幕截图中获得的图像吗?当然,一些格式/扩展会比其他格式/扩展更好。 你是什么意思的文本输入? 不,这不是屏幕截图,我们有输入文本框,我们使用的是 C# 【参考方案1】:

使用imagemagick 在图像上呈现文本(在服务器上)

由于您使用的是 C#,因此您还可以直接使用 .Net 类进行位图和字体操作(使用如下类:System.Drawing.BitmapSystem.Drawing.Graphics

【讨论】:

【参考方案2】:

好的,假设你想在 C# 中的图像上绘制一个字符串,你需要在这里使用 System.Drawing 命名空间:

private Image DrawText(String text, Font font, Color textColor, Color backColor)

    //first, create a dummy bitmap just to get a graphics object
    Image img = new Bitmap(1, 1);
    Graphics drawing = Graphics.FromImage(img);

    //measure the string to see how big the image needs to be
    SizeF textSize = drawing.MeasureString(text, font);

    //free up the dummy image and old graphics object
    img.Dispose();
    drawing.Dispose();

    //create a new image of the right size
    img = new Bitmap((int) textSize.Width, (int)textSize.Height);

    drawing = Graphics.FromImage(img);

    //paint the background
    drawing.Clear(backColor);

    //create a brush for the text
    Brush textBrush = new SolidBrush(textColor);

    drawing.DrawString(text, font, textBrush, 0, 0);

    drawing.Save();

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

    return img;


此代码将首先测量字符串,然后创建正确大小的图像。

如果要保存此函数的返回,只需调用返回图像的Save方法即可。

【讨论】:

“Image img = new Bitmap(0, 0);”行不起作用:您无法创建 0 尺寸的图像。改成“new Bitmap(1, 1)”,就可以了。 如果您在drawing.DrawString(text, font, textBrush, 0, 0); 行之前添加drawing.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;,您将获得更平滑的抗锯齿文本。 如果将字体大小加倍,然后将生成的图像大小缩小一半,您可以获得更好看的结果,这对小字体和符号字体特别有效。【参考方案3】:

我刚刚将answer 中提到的这个方法翻译成VB.NET 方法。也许这对某人有帮助。

Public Function DrawText(ByVal text As String, ByRef font As   Font, ByRef textColor As Color, ByRef backColor As Color) As Image
    ' first, create a dummy bitmap just to get a graphics object
    Dim img As Image = New Bitmap(1, 1)
    Dim drawing As Graphics = Graphics.FromImage(img)

    ' measure the string to see how big the image needs to be
    Dim textSize As SizeF = drawing.MeasureString(Text, Font)

    ' free up the dummy image and old graphics object
    img.Dispose()
    drawing.Dispose()

    ' create a new image of the right size
    img = New Bitmap(CType(textSize.Width, Integer), CType(textSize.Height, Integer))

    drawing = Graphics.FromImage(img)

    ' paint the background
    drawing.Clear(BackColor)

    ' create a brush for the text
    Dim textBrush As Brush = New SolidBrush(textColor)

    drawing.DrawString(text, font, textBrush, 0, 0)

    drawing.Save()

    textBrush.Dispose()
    drawing.Dispose()

    Return img

End Function

编辑:修正错字。

【讨论】:

谢谢弗雷迪,你为我节省了很多精力。【参考方案4】:

F#版本:


open System.Drawing

let drawText text font textColor backColor =
    let size =
      use dummyImg = new Bitmap(1, 1)
      use drawing = Graphics.FromImage(dummyImg)
      drawing.MeasureString(text, font)
    let img = new Bitmap((int size.Width), (int size.Height))
    use drawing = Graphics.FromImage(img)
    use textBrush = new SolidBrush(textColor)
    do 
      drawing.Clear(backColor)
      drawing.DrawString(text, font, textBrush, PointF())
      drawing.Save() |> ignore
    img

【讨论】:

【参考方案5】:

谢谢卡扎尔。使用 USING 处理使用后的图像/图形对象并引入最小尺寸参数的先前答案略有改进

    private Image DrawTextImage(String currencyCode, Font font, Color textColor, Color backColor) 
        return DrawTextImage(currencyCode, font, textColor, backColor, Size.Empty);
    
    private Image DrawTextImage(String currencyCode, Font font, Color textColor, Color backColor, Size minSize) 
        //first, create a dummy bitmap just to get a graphics object
        SizeF textSize;
        using (Image img = new Bitmap(1, 1)) 
            using (Graphics drawing = Graphics.FromImage(img)) 
                //measure the string to see how big the image needs to be
                textSize = drawing.MeasureString(currencyCode, font);
                if (!minSize.IsEmpty) 
                    textSize.Width = textSize.Width > minSize.Width ? textSize.Width : minSize.Width;
                    textSize.Height = textSize.Height > minSize.Height ? textSize.Height : minSize.Height;
                
            
        

        //create a new image of the right size
        Image retImg = new Bitmap((int)textSize.Width, (int)textSize.Height);
        using (var drawing = Graphics.FromImage(retImg)) 
            //paint the background
            drawing.Clear(backColor);

            //create a brush for the text
            using (Brush textBrush = new SolidBrush(textColor)) 
                drawing.DrawString(currencyCode, font, textBrush, 0, 0);
                drawing.Save();
            
        
        return retImg;
    

【讨论】:

【参考方案6】:

这是 Panayiotis 版本的 Kazar 答案,带有可选参数和文档,适合添加到库类中。

/// <summary>
/// Creates an image containing the given text.
/// NOTE: the image should be disposed after use.
/// </summary>
/// <param name="text">Text to draw</param>
/// <param name="fontOptional">Font to use, defaults to Control.DefaultFont</param>
/// <param name="textColorOptional">Text color, defaults to Black</param>
/// <param name="backColorOptional">Background color, defaults to white</param>
/// <param name="minSizeOptional">Minimum image size, defaults the size required to display the text</param>
/// <returns>The image containing the text, which should be disposed after use</returns>
public static Image DrawText(string text, Font fontOptional=null, Color? textColorOptional=null, Color? backColorOptional=null, Size? minSizeOptional=null)

    Font font = Control.DefaultFont;
    if (fontOptional != null)
        font = fontOptional;

    Color textColor = Color.Black;
    if (textColorOptional != null)
        textColor = (Color)textColorOptional;

    Color backColor = Color.White;
    if (backColorOptional != null)
        backColor = (Color)backColorOptional;

    Size minSize = Size.Empty;
    if (minSizeOptional != null)
        minSize = (Size)minSizeOptional;

    //first, create a dummy bitmap just to get a graphics object
    SizeF textSize;
    using (Image img = new Bitmap(1, 1))
    
        using (Graphics drawing = Graphics.FromImage(img))
        
            //measure the string to see how big the image needs to be
            textSize = drawing.MeasureString(text, font);
            if (!minSize.IsEmpty)
            
                textSize.Width = textSize.Width > minSize.Width ? textSize.Width : minSize.Width;
                textSize.Height = textSize.Height > minSize.Height ? textSize.Height : minSize.Height;
            
        
    

    //create a new image of the right size
    Image retImg = new Bitmap((int)textSize.Width, (int)textSize.Height);
    using (var drawing = Graphics.FromImage(retImg))
    
        //paint the background
        drawing.Clear(backColor);

        //create a brush for the text
        using (Brush textBrush = new SolidBrush(textColor))
        
            drawing.DrawString(text, font, textBrush, 0, 0);
            drawing.Save();
        
    
    return retImg;

【讨论】:

干得好。简单,有用,我喜欢你设置默认值! 很好地处理最小高度和宽度。你能帮忙处理一下最大宽度吗,这样如果文本宽度超过最大宽度,剩余的数据将进入下一行,然后根据它创建图像。

以上是关于如何在运行时即时从文本生成图像的主要内容,如果未能解决你的问题,请参考以下文章

Android:从运行时生成的文本字段中将数据保存到Firebase

从文本图像生成字体

如何使用opencv从图像中检测文本

从绘制在图像上的文本中删除顶部和底部填充

从具有正确扩展名的文本响应生成图像

在颤振中,我将如何从生成的文本框中保存文本框输入?