需求
在我们的一些发布系统项目应用中,会经常发布一些链接图标,该图标基本上以模板背景为主,并填充项目文字内容。解决方式一般会让美工进行制作处理,但当模板化以后,问题的焦点则集中在文字的显示上,因些利用程序控制文字自动填充模板背景图片,可以自动化的解决需求。
比如有如下模板:
(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 为必填参数。我们可以根据实际需要进行后续处理和改造。
方法理论上可以无限填充,但考虑实际效果,对文本内容的长度还是要有一些限制,以达到比较理想的显示效果。
到此这篇关于c#实现自动填充文字内容到指定图片的文章就介绍到这了,更多相关c#自动填充文字内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论