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

目录

需求

开发运行环境

方法设计

实现代码

AddText方法

图片转Base64

调用示例 

小结


需求

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

比如有如下模板:

(1)纯色模板

(2)图片模板

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

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

开发运行环境

操作系统: Windows Server 2019 DataCenter

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

开发工具:VS2019  C#

方法设计

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

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

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

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

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

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


请注意前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 为必填参数。我们可以根据实际需要进行后续处理和改造。

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/825014.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt 拖放功能详解:理论与实践并举的深度指南

拖放&#xff08;Drag and Drop&#xff09;作为一种直观且高效的用户交互方式&#xff0c;在现代图形用户界面中扮演着重要角色。Qt 框架提供了完善的拖放支持&#xff0c;允许开发者在应用程序中轻松实现这一功能。本篇博文将详细阐述Qt拖放机制的工作原理&#xff0c;结合详…

代码随想录阅读笔记-回溯【N皇后】

题目 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方案。 每一种解法包含一个不同的 n 皇后问题 的棋子放置方案&#xff0c;该方案中 Q 和 . 分别代表…

【2024】使用Rancher管理k8s集群和创建k8s集群

Rancher管理k8s集群及创建k8s集群。 Rancher版本为:2.8.2目录 rancher管理k8s集群rancher创建k8s集群rancher管理k8s集群 使用rancher管理已经存在的k8s集群。 本部分内容需要自行准备好k8s集群及rancher平台,部署请看本人其他文章 。 登录到rancher平台后,点击集群管理,…

C#:闰年判断

任务描述 编写程序&#xff0c;完成如下功能&#xff1a;从键盘输入任意年份year&#xff0c;判别该年份是否闰年。 为避免出现格式错误&#xff0c;请直接拷贝粘贴题目中给的格式字符串和提示信息到你的程序中。 ####输入 从键盘任意输入一个年份 输出 根据是否闰年进行输出…

JavaScript eval() 函数

定义和用法 eval() 函数计算 JavaScript 字符串&#xff0c;并把它作为脚本代码来执行。 如果参数是一个表达式&#xff0c;eval() 函数将执行表达式。如果参数是Javascript语句&#xff0c;eval()将执行 Javascript 语句。 语法 eval(string) 实例 执行JavaScript代码或…

部署wordpress

查看别名type ll ll 是 ls -l --colorauto 的别名 设置别名alias alias ymyum install -y 使用别名ym nginx 取消别名unalias ym 基于LNMP做一个wordpress nginx mysql 5.7 PHP 7.4 1、linux基本环境 修改主机名 hostnamectl set-hostname $name 关闭防火墙及selinux …

关于FastJson转换map集合为json字符串解析时格式出错的问题

在Java中使用Fastjson将包含Map类型key的Map集合转换为String时&#xff0c;如果直接使用Fastjson的JSON.toJSONString()方法&#xff0c;可能会因为JavaScript的安全性限制&#xff08;例如对象的key必须是字符串&#xff09;而在前端JavaScript解析时出现问题。 因为当 转换时…

113 如何排查 cpu 过高的业务进程

前言 又是一个面试问题, 呵呵 之前碰到的 一个 java 进程 cpu 占用率过高, 应该如何排查? 对于这种问题, 第一反应就是 jstack, pstack, 然后仔细观察多次堆栈信息结果的 重复率较高的代码 因此 我给出的思路是, 写脚本 多次 jstack 目标进程, 然后 再统计分析一下 出现频…

LLM理解v1

答疑 什么是知识库&#xff1f; LLM&#xff08;Large Language Models&#xff0c;大型语言模型&#xff09;如GPT系列&#xff0c;通常是基于海量的文本数据进行训练的。它们通过分析和理解这些数据来生成回答、撰写文章、解决问题等。当我们提到LLM的“本地知识库”时&…

Stable Diffusion 模型分享:CyberRealistic XL(真实)cyberrealisticXL_v11VAE.safetensors

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八下载地址模型介绍

mybatisPlus数据字段填充

这里用到的时实体类User import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import lombok.…

揭秘Arthas:如何轻松查看入参的命令

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 大家好&#xff0c;我是你们的博主。今天我要和大家分享一个非常实用的技术技巧&#xff0c;那就是如何使用Arthas来查看入参的命令。我相信这个技巧对于那些想要提升自己Java开发技能的程序员来说&#xff0c;一定是…

压缩感知的概述梳理(1)

参考文献 An efficient visually meaningful image compression and encryption scheme based on compressive sensing and dynamic LSB embedding 基本内容 基本关系梳理 压缩感知核心元素 信号 x 长度&#xff1a;N动态稀疏或可用变换表示&#xff1a;x &#x1d74d;s …

如何将低分辨率的视频变高清,使用AI工具分辨率画质增强至1080P、4K或者8K(附工具)

环境&#xff1a; Topaz Video AI 5.0 问题描述&#xff1a; 如何将低分辨率的视频变高清&#xff0c;使用AI工具分辨率画质增强至1080P、4K或者8K 原视频 增强1080P 解决方案&#xff1a; 1.打开软件&#xff0c;导入要处理的视频&#xff08;工具在本文最后附上&#xf…

C 排序算法

冒泡排序 冒泡排序&#xff08;英语&#xff1a;Bubble Sort&#xff09;是一种简单的排序算法。它重复地走访过要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果他们的顺序&#xff08;如从大到小、首字母从A到Z&#xff09;错误就把他们交换过来。 过程演示&…

数据一致性和事务一致性是两个不同的问题

Paxos、Raft和Zab都是用于解决分布式系统中的数据一致性问题的算法或协议。 2PC和3PC则是用于保证分布式系统中的事务一致性问题的协议。 在分布式系统中&#xff0c;数据一致性和事务一致性是两个不同的问题。但是&#xff0c;为了解决分布式系统中的数据一致性问题&#xf…

智慧城市同城V4-v2.7.1源码全开源

智慧城市同城V4-2.7.1修复更新记录 修复家政服务者页面进入服务项目详情时错误的问题 修复服务商分账业务员和分销商身份重叠时无法分账的问题 修复团购商品商户自负营销设置时无效的问题 修复购物车下单时可能导致订单无商户的问题 修复家政服务项目列表搜索后不显示项目…

学习笔记------时序约束之时钟周期约束

本文摘自《VIVADO从此开始》高亚军 主时钟周期约束 主时钟&#xff0c;即从FPGA的全局时钟引脚进入的时钟或者由高速收发器输出的时钟。 对于时钟约束&#xff0c;有三个要素描述&#xff1a;时钟源&#xff0c;占空比和时钟周期。 单端时钟输入 这里我们新建一个工程&#x…

芯片灌封胶是什么?有哪些优点?

芯片灌封胶是什么&#xff1f;有哪些优点&#xff1f; 芯片灌封胶是一种液态复合物&#xff0c;通过机械或手工方式精准灌入装有电子元件、线路的器件内&#xff0c;在常温或加热条件下固化成为性能优异的热固性高分子绝缘材料。它广泛应用于电子元器件的粘接、密封、灌封和涂…