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

news2024/9/20 2:51:55

目录

需求

开发运行环境

方法设计

实现代码

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;  // 初次估计先用文字区域高度作为文字字体大小,后面再做调整,单位为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 为必填参数。我们可以根据实际需要进行后续处理和改造。

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

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

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

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

相关文章

数字化校园在职校教育中的价值和前景

在当今信息化浪潮中&#xff0c;职校教育正以前所未有的速度迈入智慧校园时代。数字化校园以其强大的功能和广泛的适用性&#xff0c;正在深刻地改变职校的教学模式、管理模式以及学生的学习方式&#xff0c;助力职校教育实现高质量、高效率、个性化的转型&#xff0c;如何利用…

微信小程序小游戏开发,微信开发者工具提示该目录下的项目(wxapp2)已在工具中创建,怎么办

微信小程序小游戏开发&#xff0c;微信开发者工具提示该目录下的项目&#xff08;wxapp2&#xff09;已在工具中创建&#xff0c;怎么办 情况描述&#xff0c; 导入一个项目的时候&#xff0c;导入成了小游戏项目了 想换成小游戏项目&#xff0c;变不了了&#xff0c;提示 “…

Fanuc机器人 Karel 编程学习(五)---简单的Socket通信

Fanuc Karel编写Socket程序和上位机进行通信。 一&#xff1a;环境配置(ROBOGUIDE) 1.1机器人系统变量设置 MENU-------> SYSTEM------> Variables------->$KERAL_ENB 设置为1 1.2 IP地址设定 MENU---->SETUP---->Host Comm 选择 F3【DETAIL】进入IP设置…

【图论 单源最短路】100276. 最短路径中的边

本文时间知识点 单源最短路 图论知识汇总 LeetCode100276. 最短路径中的边 给你一个 n 个节点的无向带权图&#xff0c;节点编号为 0 到 n - 1 。图中总共有 m 条边&#xff0c;用二维数组 edges 表示&#xff0c;其中 edges[i] [ai, bi, wi] 表示节点 ai 和 bi 之间有一条…

Topaz Photo AI 3.0.0 (macOS Universal) - AI 图片修复工具

Topaz Photo AI 3.0.0 (macOS Universal) - AI 图片修复工具 Maximize Image Quality with AI 请访问原文链接&#xff1a;Topaz Photo AI 3.0.0 (macOS Universal) - AI 图片修复工具&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sy…

FK中的一些方法

1. 隔离法与整体法 目标&#xff1a;对一个拉新邀请任务&#xff0c;识别出其中的作弊用户。 欺诈类的数据&#xff0c;黑样本不足&#xff0c;需要自己去找&#xff0c;可按IP、昵称、手机号相似性等。虽然有 会员等级、注册时长、注册地址、成交订单等特征&#xff0c;但分类…

STM32 HAL库F103系列之ADC实验(一)

ADC工作原理&#xff1a; 1、输入通道&#xff1a; 2、转换序列&#xff1a; A/D转换被组织为两组&#xff1a;规则组&#xff08;常规转换组&#xff09;和注入组&#xff08;注入转换组&#xff09; 规则组最多可以有16个转换&#xff0c;注入组最多有4个转换 规则组和注入…

视频素材库哪里最好?8个视频素材免费商用

在视频创作的世界里&#xff0c;寻找那些能够完美匹配你的想法并加以实现的视频素材是一项既令人兴奋又充满挑战的任务。无论你的目标是提升视频质量、增强视觉效果&#xff0c;还是简单地想要让你的作品更加出色&#xff0c;这里有一系列全球精选的视频素材网站&#xff0c;它…

014Node.js时间格式包silly-datetime安装与使用

下载&#xff1a; https://www.npmjs.com/网站上下载silly-datetime 安装 npm i silly-datetime --save var sd require(silly-datetime);console.log(new Date()); //2024-04-18T04:40:38.505Zvar dsd.format(new Date(), YYYY-MM-DD HH:mm);console.log(d); //2024…

【C++类和对象】const成员函数及流插入提取

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

2024第三届中国力触觉技术及应用会议,将于5月24-26日在天津举办,搜维尔科技与您共探触觉传感器与力触觉感知新技术

大会介绍 2024第三届中国力触觉技术及应用会议”将于2024年5月24-26日在中国天津举办。 本届会议以“感知赋能未来&#xff0c;触觉助力世界”为主题&#xff0c;聚焦力触觉传感器与力触觉感知技术&#xff0c;持续关注行业领域热点&#xff0c;探讨技术前沿&#xff0c;融合多…

Jira搭建过程

看到很多小伙伴对jira有兴趣,我们今天就来分享一下jira的搭建吧 首先要明白jira是什么? 看来搭建jira也是我们测试人员需要具备的技能之一了.下面是详细的大家步骤: 1.系统环境准备 Centos 7.5 Mysql 5.6 Java1.8 2.软件安装包 atlassian-jira-software-7.13.0-x64.bin …

数据结构——7.3 树形查找

7.3 树形查找 概念 二叉排序树&#xff08;BST&#xff09; 二叉排序树&#xff08;Binary Sort Tree&#xff0c;BST&#xff09;&#xff0c;又称为二叉查找&#xff08;搜索&#xff09;树&#xff08;Binary Search Tree&#xff09;&#xff0c;是一种特殊的二叉树&am…

OpenHarmony 网络与连接—RPC连接

介绍 本示例使用ohos.rpc 相关接口&#xff0c;实现了一个前台选择商品和数目&#xff0c;后台计算总价的功能&#xff0c;使用rpc进行前台和后台的通信。 效果预览 使用说明&#xff1a; 点击商品种类的空白方框&#xff0c;弹出商品选择列表&#xff0c;选择点击对应的商品…

MATLAB实现遗传算法优化BP神经网络预测数值(GABP)

遗传算法&#xff08;Genetic Algorithm, GA&#xff09;和反向传播&#xff08;Back Propagation, BP&#xff09;神经网络是两种强大的算法&#xff0c;分别用于优化和机器学习。将遗传算法与BP神经网络结合&#xff0c;可以利用遗传算法的全局搜索能力来优化BP神经网络的初始…

stm32中断发送接收数据

配置hal库 1配置时钟 2配置uart 3打开中断 程序结构 uart中断函数 中断接收和发送函数 HAL_UART_Receive_IT()&#xff1a;启动中断驱动的接收过程&#xff0c;当接收到指定数量的字节后会产生中断&#xff0c;并调用HAL_UART_RxCpltCallback()回调函数。 HAL_StatusTypeD…

【MIT6.S081】Lab4: traps(详细解答版)

实验内容网址&#xff1a;https://xv6.dgs.zone/labs/requirements/lab4.html 本实验的代码分支&#xff1a;https://gitee.com/dragonlalala/xv6-labs-2020/tree/traps2/ Backtrace 关键点:trapframe、栈 思路&#xff1a; 这道题的关键是栈结构&#xff0c;先阅读xv6中关于栈…

SpringCloud技术—Docker详解、案例展示

简介&#xff1a;Docker 将应用程序与该程序的依赖&#xff0c;打包在一个文件里面。运行这个文件&#xff0c;就会生成一个虚拟容器。程序在这个虚拟容器里运行&#xff0c;就好像在真实的物理机上运行一样。有了Docker&#xff0c;就不用担心环境问题。 总体来说&#xff0c;…

代码随想录刷题|一刷总结

文章目录 一刷总结一、 成果汇报1、leetcode提交记录2、博客更新记录 二、 经验总结2.1.刷过的所有题型2.1.1、数组2.1.2、链表2.1.3、哈希表2.1.4、字符串2.1.5、栈与队列2.1.6、二叉树2.1.7、回溯2.1.8、贪心2.1.9、动态规划2.1.10、单调栈 2.2、做得好的2.3、做得不好的2.4、…

行业模板|DataEase批发零售大屏模板推荐

DataEase开源数据可视化分析平台于2022年6月发布模板市场&#xff08;https://templates-de.fit2cloud.com&#xff09;&#xff0c;并于2024年1月新增适用于DataEase v2版本的模板分类。模板市场旨在为DataEase用户提供专业、美观、拿来即用的大屏模板&#xff0c;方便用户根据…