目录
需求
开发运行环境
方法设计
实现代码
AddText方法
图片转Base64
调用示例
小结
需求
在我们的一些发布系统项目应用中,会经常发布一些链接图标,该图标基本上以模板背景为主,并填充项目文字内容。解决方式一般会让美工进行制作处理,但当模板化以后,问题的焦点则集中在文字的显示上,因些利用程序控制文字自动填充模板背景图片,可以自动化的解决需求。
比如有如下模板:
(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; // 初次估计先用文字区域高度作为文字字体大小,后面再做调整,单位为pxSystem.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 为必填参数。我们可以根据实际需要进行后续处理和改造。
方法理论上可以无限填充,但考虑实际效果,对文本内容的长度还是要有一些限制,以达到比较理想的显示效果。
感谢您的阅读,希望本文能够对您有所帮助。