目录
  • 需求
  • 开发运行环境
  • 方法设计
  • 实现代码
    • AddText方法
    • 图片转Base64
    • 调用示例 
  • 小结

    需求

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

    比如有如下模板:

    (1)纯色模板

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

    (2)图片模板

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

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

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

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

    开发运行环境

    操作系统: 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 为必填参数。我们可以根据实际需要进行后续处理和改造。

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

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。