C# 自动填充文字内容到指定图片

简介: C# 自动填充文字内容到指定图片

需求

在我们的一些发布系统项目应用中,会经常发布一些链接图标,该图标基本上以模板背景为主,并填充项目文字内容。解决方式一般会让美工进行制作处理,但当模板化以后,问题的焦点则集中在文字的显示上,因些利用程序控制文字自动填充模板背景图片,可以自动化的解决需求。

比如有如下模板:

(1)纯色模板

(2)图片模板

如以上的模板,我们需要在指定的区域填充文字(比如项目名称、课程标题等等),简单的描述,就是随着文字的增多而将字体变小和折行。

如上图中标题文字增加,则显示如下:

开发运行环境

操作系统: Windows Server 2019 DataCenter

.net版本: .netFramework4.0 或以上

开发工具:VS2019  C#

方法设计

设计 AddText 方法,返回 System.Drawing.Bitmap 对象,设计如下表:

序号 参数 类型 说明
1 imgPath string 模板图片文件路径
2 saveImgPath string 可导出的成品图片文件路径
3 baselen int 标题基础计算长度,一般传递标题的总长度(.Length)
4 locationLeftTop string

文字输出区域的左上角坐标 Left: x1 ,Top: y1

参数形式以逗号分隔,如:20,100
5 locationRightBottom string

文字输出区域的右下角坐标 Right: x2 ,Bottom: y2

参数形式以逗号分隔,如:120,200
6 text string 要写入的文字内容
7 fontName string 字体,非必传项,默认为 "华文行楷"

请注意前6个参数为必填写项,且 locationLeftTop 和 locationRightBottom 请传递合理的数值。

实现代码

AddText方法

public  System.Drawing.Bitmap AddText(string imgPath,string saveImgPath,int baselen, string locationLeftTop, string locationRightBottom, string text, string fontName = "华文行楷")
{
    System.Drawing.Image img = System.Drawing.Image.FromFile(imgPath);
 
    int width = img.Width;
    int height = img.Height;
    System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width, height);
    System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bmp);
 
    // 计算文字区域
    // 左上角
    string[] location = locationLeftTop.Split(',');
    float x1 = float.Parse(location[0]);
    float y1 = float.Parse(location[1]);
    // 右下角
    location = locationRightBottom.Split(',');
    float x2 = float.Parse(location[0]);
    float y2 = float.Parse(location[1]);
    // 区域宽高
    float fontWidth = x2 - x1;
    float fontHeight = y2 - y1;
 
    float fontSize = fontHeight;  // 初次估计先用文字区域高度作为文字字体大小,后面再做调整,单位为px
 
    System.Drawing.Font font = new System.Drawing.Font(fontName,18, System.Drawing.GraphicsUnit.Pixel);
    System.Drawing.SizeF sf = graph.MeasureString(text, font);
 
 
    // 最终的得出的字体所占区域一般不会刚好等于实际区域
    // 所以根据两个区域的相差之处再把文字开始位置(左上角定位)稍微调整一下
    string title = text;
    text = "";
    int gs = title.Length / baselen;
    if (title.Length % baselen != 0)
    {
        gs++;
    }
    string[] lines = new string[gs];
    int startpos = 0;
    
    for (int i = 0; i < gs; i++)
    {
        int len = title.Length < baselen ? title.Length : baselen;
        lines[i] = title.Substring(0, len);
        startpos += len;
        title = title.Substring(len);
        text += lines[i] + "\r\n";
    }
 
    x1 += (fontWidth - sf.Width) / 2;
    y1 += (fontHeight - sf.Height) / 2;
    x1 = (width - baselen * 18) / 2;
    y1 = (height - lines.Length * 18) / 2;
    graph.DrawImage(img, 0, 0, width, height);
 
    graph.DrawString(text, font, new System.Drawing.SolidBrush(System.Drawing.Color.White), x1, y1);
    
    graph.Dispose();
    img.Dispose();
    bmp.Save(saveImgPath,System.Drawing.Imaging.ImageFormat.Jpeg);
    return bmp;
}

图片转Base64

            public string ImgToBase64String(string Imagefilename,bool outFullString=false)
            {
                try
                {
                    System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(Imagefilename);
 
                    MemoryStream ms = new MemoryStream();
                    //            bmp.Save(ms,ImageFormat.Jpeg)
                    System.Drawing.Imaging.ImageFormat iformat = System.Drawing.Imaging.ImageFormat.Jpeg;
                    string extension = System.IO.Path.GetExtension(Imagefilename).Replace(".", "").ToLower();
                    if (extension == "bmp")
                    {
                        iformat = System.Drawing.Imaging.ImageFormat.Bmp;
                    }
                    else if (extension == "emf")
                    {
                        iformat = System.Drawing.Imaging.ImageFormat.Emf;
                    }
                    else if (extension == "exif")
                    {
                        iformat = System.Drawing.Imaging.ImageFormat.Exif;
                    }
                    else if (extension == "gif")
                    {
                        iformat = System.Drawing.Imaging.ImageFormat.Gif;
                    }
                    else if (extension == "icon")
                    {
                        iformat = System.Drawing.Imaging.ImageFormat.Icon;
                    }
                    else if (extension == "png")
                    {
                        iformat = System.Drawing.Imaging.ImageFormat.Png;
                    }
                    else if (extension == "tiff")
                    {
                        iformat = System.Drawing.Imaging.ImageFormat.Tiff;
                    }
                    else if (extension == "wmf")
                    {
                        iformat = System.Drawing.Imaging.ImageFormat.Wmf;
                    }
 
                    bmp.Save(ms, iformat);
                    byte[] arr = new byte[ms.Length];
                    ms.Position = 0;
                    ms.Read(arr, 0, (int)ms.Length);
                    ms.Close();
                    bmp.Dispose();
                    string rv=Convert.ToBase64String(arr);
                    if (outFullString == true)
                    {
                        rv = "data:image/" + extension + ";base64," + rv;
                    }
                    return rv;
                }
                catch (Exception ex)
                {
                    return null;
                }
            }

请注意 bool outFullString=false,默认为false,表示输出纯Base64编码。

如果直接作用于Image对象的 ImageUrl,则需要设置为true。即在生成结果前加上 "data:image/jpeg;base64," + base64 字样。

调用示例

 
 
 
void Page_load(Object sender, EventArgs e){
 
    string path = "D:\\website\\test\\";
    string title="数据库存储过程从入门到精通";
    int baselen = title.Length;
    string x1_y1="0,0";
    string x2_y2="240,80";
 
    AddText(path + "bg.bmp", path + "bg2.jpg", baselen, x1_y1, x2_y2, title);
 
    Image1.ImageUrl = ImgToBase64String(path + "bg2.jpg", true);
 
}
 

其中 Image1 为 Asp.net WebUI 中的 Image 对象。

小结

本方法同时输出 saveImgPath 目标成品文件路径和返回Bitmap对象,saveImgPath 为必填参数。我们可以根据实际需要进行后续处理和改造。

方法理论上可以无限填充,但考虑实际效果,对文本内容的长度还是要有一些限制,以达到比较理想的显示效果。

感谢您的阅读,希望本文能够对您有所帮助。

相关文章
|
2月前
|
数据采集 JavaScript C#
C#图像爬虫实战:从Walmart网站下载图片
C#图像爬虫实战:从Walmart网站下载图片
C#WPF 图片在显示时没有问题,但在运行时图片显示不出来的解决
选中项目,点击右上角的显示全部文件按钮,会将默认隐藏的文件显示出来,选中所需图片,右键,添加到项目,然后选择图片查看属性,生成操作选择resource。完毕。本人目前的解决方案。
445 41
C#WPF 图片在显示时没有问题,但在运行时图片显示不出来的解决
|
5月前
|
C#
技术经验分享:c#拆分字符串英文和数字(包括国外所以文字)
技术经验分享:c#拆分字符串英文和数字(包括国外所以文字)
35 0
技术经验分享:c#拆分字符串英文和数字(包括国外所以文字)
|
6月前
|
存储 算法 C#
C# 生成指定图片的缩略图
C# 生成指定图片的缩略图
|
6月前
|
C# 开发工具 数据安全/隐私保护
C# 给图片添加文字水印
C# 给图片添加文字水印
|
6月前
|
API C# 数据安全/隐私保护
C# 实现网页内容保存为图片并生成压缩包
C# 实现网页内容保存为图片并生成压缩包
|
11月前
|
API C#
C# 调用系统“API“设置图片为“桌面壁纸“
C# 调用系统“API“设置图片为“桌面壁纸“
|
C#
C# 图片RGB处理判断
C# 图片RGB处理判断 需要:根据一张原始图的RGB平均值和新的图片的RGB平均值的差距,来判断图中是否出现除原图中物体外的其他物体 前提:.Net framework 4.8 及以上 示例代码: 程序集:using System;using System.Drawing;using System.Drawing.Drawing2D;using System.Drawing.Imagin...
53 0
|
17天前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
30 3