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平台后,点击集群管理,…

部署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 …

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

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

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.…

压缩感知的概述梳理(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;错误就把他们交换过来。 过程演示&…

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

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

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

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

微信小程序自定义导航栏定位及胶囊按钮图解

在自定义小程序导航栏时&#xff0c;右上角的胶囊&#xff08;MenuButton&#xff09;在不同机型测试&#xff0c;会发现很难适配。 实测中 不同的手机&#xff0c;胶囊高度不一样、状态栏高度不一样。与模拟器显示的情况是不一样的。 由于小程序在不同的手机上顶部布局会发生…

解锁数据潜能:构建高效数据仓库的策略与实践

在数字化时代&#xff0c;数据已成为企业最宝贵的资产之一。然而&#xff0c;随着数据量的激增&#xff0c;企业面临着数据管理的诸多挑战。如何有效地利用这些数据&#xff0c;支持企业的决策和运营&#xff0c;成为每个企业都需要解答的问题。数据仓库的建设和数据的合理分层…

B1100 校庆

输入样例&#xff1a; 5 372928196906118710 610481197806202213 440684198612150417 13072819571002001X 150702193604190912 6 530125197901260019 150702193604190912 220221196701020034 610481197806202213 440684198612150417 370205198709275042 输出样例&#xff1a;…

LInux shell编程之基础语法

目录 1、shell概述 1.1、查看Linux 提供的 Shell 解析器 1.2、bash 和 sh 的关系 1.3、查看系统&#xff08;centos&#xff09;默认使用的解释器 2、脚本的基础使用 2.1、脚本的格式 2.2、脚本的执行方式 方式一&#xff1a;采用 bash / sh 脚本的相对路径或绝对路径…

Intel性能分析工具Vtune安装和使用简介

一、介绍 Intel Vtune profiler是用于串行和多线程应用程序的性能分析工具&#xff0c;可以帮助软件开发人员对应用程序的性能问题进行分析&#xff0c;支持包括linux和windows在内的多种操作系统。主要功能包括&#xff1a; 性能分析&#xff1a;可以对应用程序进行深入的性…

单片机入门还能从51开始吗?

选择从51单片机开始入门还是直接学习基于ARM核或RISC核的单片机&#xff0c;取决于学习目标、项目需求以及个人兴趣。每种单片机都有其特定的优势和应用场景&#xff0c;了解它们的特点可以帮助你做出更合适的选择。 首先&#xff0c;我们说一下51单片机的优势&#xff1a; 成熟…

网络安全:绕过 MSF 的一次渗透测试

这次渗透的主站是 一个 Discuz!3.4 的搭建 违法招 piao 网站&#xff0c; 配置有宝塔 WAF 用 Discuz!ML 3.X 的漏洞进行攻击&#xff0c;但是没有成功 发现主站外链会有一个发卡网&#xff0c;引导人们来这充值&#xff0c;是 某某发卡网&#xff0c;而且域名指向也是主站的 ip…