根据图片模板动态生成图片(Java)

根据图片模板生成图片

  • 背景
  • 流程简介
  • 代码实现

背景

根据提供的证书模板生成对应证书,证书内容有,姓名,身份证号,证书名称,证书编号,发证日期
根据用户达成的条件自动生成证书图片。

证书模板如下(原图):
在这里插入图片描述

流程简介

根据模板生成图片的流程如下

  1. 读取 图片模板
  2. 确定 需要替换内容的坐标
  3. 确定需要替换的内容
  4. 生成图片并保存

下面分别按上述步骤介绍方法

  1. 读取图片模板
//将图片链接转化为可操作的 Image对象
private BufferedImage readImageFromUrl(String template) {try {URL url = new URL(template);return ImageIO.read(url);} catch (IOException e) {}return null;}
//将本地图片转化为可操作的 Image对象
private BufferedImage readImageFromPath(String template) {try(FileInputStream input = new FileInputStream(new File(template))) {return ImageIO.read(input);} catch (IOException e) {}return null;
}
  1. 确定需要替换的内容坐标

如果有设计稿的话,直接在设计稿上可以清楚的看到内容坐标。

如果没有设计稿,下面推荐一个在线PS网站,将图片托进来也可以清楚的获取需要替换的内容坐标

https://ps.gaoding.com/#/

注意:画布是坐标原点在左上角
在这里插入图片描述
所以姓名所在的位置坐标应该是 (578,832)

  1. 确定需要替换的内容并替换
    确定好替换的内容,包括字体大小,颜色等
Graphics2D g = sourceImage.createGraphics();
g.setColor(Color.RED);//设置画笔颜色
g.setFont(new Font("微软雅黑",Font.PLAIN,58));// 更改字体、样式和大小
//替换内容
g.drawString("张三", 578, 832);

注意:画图时是从左下脚开始画的,所以drawString方法填入的坐标点,是准备填入内容的的左下角的位置
如下图所示:
在这里插入图片描述
4. 生成新的图片

将Image对象转为文件

//图片生成到本地
File outputImageFile = new File("output_image.jpg"); // 输出图片文件路径
ImageIO.write(modifiedImage, "jpg", outputImageFile);//或者写入输出流,然后上传到服务器
try(ByteArrayOutputStream outputStream = new ByteArrayOutputStream()){ImageIO.write(newImage,ext,outputStream);
}catch (IOException e){
}

代码实现

这里做了简单的代码抽象
抽象一些辅助类:用来存储模板信息,替换位置,以及字体,内容等

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PicWithParams {//模板地址private String picTemplate;//替换的参数列表private List<PicParams> paramsList;
}@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
class PicParams {/*字体*/private Font font;/*画笔颜色*/private Color color;/*正文*/private String content;/*x坐标*/private Integer xPoint;/*y坐标*/private Integer yPoint;/*位置*/private TextAlign textAlign;
}enum TextAlign {/*居中*/CENTER,/*左对齐*/LEFT,/*右对齐*/RIGHT;
}

核心处理类

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;public class ProduceImageService {private static String FONT_NAME = "微软雅黑";public void drawImage(PicWithParams picWithParams) {BufferedImage templateImage = readImageFromPath(picWithParams.getPicTemplate());BufferedImage newImage = drawImageWithParams(templateImage, picWithParams.getParamsList());storeImage(newImage);}private void storeImage(BufferedImage newImage) {File outputImageFile = new File("output.jpg"); // 输出图片文件路径try {ImageIO.write(newImage, "jpg", outputImageFile);} catch (IOException e) {}System.out.println("Generated image saved to: " + outputImageFile.getAbsolutePath());}private BufferedImage drawImageWithParams(BufferedImage sourceImage, List<PicParams> paramsList) {if(null == sourceImage){throw new IllegalArgumentException("参数异常");}Graphics2D g = sourceImage.createGraphics();try {for (PicParams param : paramsList) {g.setColor(param.getColor());g.setFont(param.getFont());FontMetrics metrics = g.getFontMetrics();switch (param.getTextAlign()){case LEFT:g.drawString(param.getContent(), param.getXPoint(), param.getYPoint());break;case RIGHT:g.drawString(param.getContent(), param.getXPoint() - metrics.stringWidth(param.getContent()), param.getYPoint());break;case CENTER:default:g.drawString(param.getContent(), param.getXPoint() - metrics.stringWidth(param.getContent()) / 2, param.getYPoint());}}} finally {g.dispose();}return sourceImage;}private BufferedImage readImageFromUrl(String template) {try {URL url = new URL(template);return ImageIO.read(url);} catch (IOException e) {}return null;}private BufferedImage readImageFromPath(String template) {try(FileInputStream input = new FileInputStream(new File(template))) {return ImageIO.read(input);} catch (IOException e) {}return null;}public static void main(String[] args) {ProduceImageService ImageService = new ProduceImageService();PicWithParams picWithParams = ImageService.getParams();ImageService.drawImage(picWithParams);}private PicWithParams getParams() {List<PicParams> picParams = new ArrayList<>();picParams.add(PicParams.builder().content("张三").xPoint(578).yPoint(832).color(Color.black).textAlign(TextAlign.CENTER).font(new Font(FONT_NAME,Font.PLAIN,58)).build());picParams.add(PicParams.builder().content("353638199905022815").xPoint(1300).yPoint(832).color(Color.black).textAlign(TextAlign.CENTER).font(new Font(FONT_NAME,Font.PLAIN,54)).build());picParams.add(PicParams.builder().content("架构师认证").xPoint(1000).yPoint(900+53).color(Color.black).textAlign(TextAlign.CENTER).font(new Font(FONT_NAME,Font.PLAIN,54)).build());picParams.add(PicParams.builder().content("RJ12345678900001").xPoint(410).yPoint(1164+25).color(Color.black).textAlign(TextAlign.LEFT).font(new Font(FONT_NAME,Font.PLAIN,33)).build());picParams.add(PicParams.builder().content("2024年2月11日").xPoint(1385).yPoint(1164+30).color(Color.black).textAlign(TextAlign.LEFT).font(new Font(FONT_NAME,Font.PLAIN,33)).build());return PicWithParams.builder().picTemplate("证书.jpg").paramsList(picParams).build();}
}

内容替换后:
在这里插入图片描述

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

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

相关文章

【51单片机项目】基于51单片机自制多功能小键盘/模拟USB键盘【附源码】(STC89C52RC+CH9328)

目录 一、效果展示 二、创作灵感 三、硬件电路 注意事项 工作原理 四、源码 main.c 五、附录 CH9328工作原理 CH9328的模式选择 ​编辑 全键盘键码值表 参考链接 一、效果展示 该小键盘具有三种功能&#xff1a; 1、自动输入开机密码 2、每隔一段时间自动按下ct…

多模态大模型训练数据量以及训练方式

多模态大模型系列&#xff1a;LLaVALLaVA1.5/1.6LLaVA-Med - 知乎就在前两天LLaVA 1.6发布了&#xff0c;带来了更大的分辨率&#xff0c;更强的LLM&#xff0c;在最后补充了这一部分的介绍。 LLaVA repo&#xff1a;https://github.com/haotian-liu/LLaVA/ LLaVA 1.0&#xff…

《C语言深度解剖》(9):深度剖析数据在内存中的存储

&#x1f921;博客主页&#xff1a;醉竺 &#x1f970;本文专栏&#xff1a;《C语言深度解剖》 &#x1f63b;欢迎关注&#xff1a;感谢大家的点赞评论关注&#xff0c;祝您学有所成&#xff01; ✨✨&#x1f49c;&#x1f49b;想要学习更多数据结构与算法点击专栏链接查看&am…

操作系统安全:Windows与Linux的安全标识符,身份鉴别和访问控制

「作者简介」&#xff1a;2022年北京冬奥会中国代表队&#xff0c;CSDN Top100&#xff0c;学习更多干货&#xff0c;请关注专栏《网络安全自学教程》 操作系统有4个安全目标&#xff0c;也就是说想要保证操作系统的安全&#xff0c;就必须实现这4个需求&#xff1a; 标识系统…

系统安全与应用(1)

目录 1、账号安全管理 &#xff08;1&#xff09;禁止程序用户登录 &#xff08;2&#xff09;锁定禁用长期不使用的用户 &#xff08;3&#xff09;删除无用的账号 &#xff08;4&#xff09;禁止账号和密码的修改 2、密码安全管理 设置密码有效期 1&#xff09;针对已…

一句话或一张图讲清楚系列之——ISERDESE2的原理

主要参考&#xff1a; https://blog.csdn.net/weixin_50810761/article/details/137383681 xilinx原语详解及仿真——ISERDESE2 作者&#xff1a;电路_fpga https://blog.csdn.net/weixin_45372778/article/details/122036112 Xilinx ISERDESE2应用笔记及仿真实操 作者&#x…

K8S Prometheus Springboot Actuator ServiceMonitor配置

用于展示Springboot Actuator监控内容 引入Springboot相关的监控配置包 Springboot pom配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><depende…

K8s: Ingress对象, 创建Ingress控制器, 创建Ingress资源并暴露服务

Ingress对象 1 &#xff09;概述 Ingress 是对集群中服务的外部访问进行管理的 API 对象&#xff0c;典型的访问方式是 HTTPIngress-nginx 本质是网关&#xff0c;当你请求 abc.com/service/a, Ingress 就把对应的地址转发给你&#xff0c;底层运行了一个 nginx但 K8s 为什么不…

modelsim波形高度异常,值为X

一、问题 波形高度异常&#xff0c;忽高忽低&#xff0c;正常波形高电平和低电平是统一高度的 timescale 1ns/1nsmodule key_test_tb();//parameter define parameter CLK_PERIOD 20; parameter CNT_MAX 25d25; //仅用于仿真,对应 500nsreg sys_clk; //周期 20ns reg d; wir…

ffmpeg初体验

一&#xff1a;安装 sudo yum install epel-release -y sudo yum update -ysudo rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro sudo rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpmyum -y install …

Vs Code npm install 报错解决方法

用的人家的前端框架发现是封装过的&#xff0c;要修改人家前端的话还得把前端源码放在Vs Code 上运行&#xff0c;后端放在IDEA上运行&#xff0c;然后前后端并行开发&#xff0c;在配置前端环境时遇到&#xff1a; npm install 这个的原因是我把node下载到D盘了权限不够框框爆…

android学习笔记(五)-MVP模式

1、MVP模式demo的实现&#xff0c;效果下&#xff1a; 2、创建一个Fruit类&#xff1a; package com.example.listview; //Fruit类就是Model&#xff0c;表示应用程序中的数据对象。 public class Fruit {private int imageId;private String name;private String price;publi…

代码随想录算法训练营Day6 | 242.有效的字母异位词 ●349. 两个数组的交集 ● 202. 快乐数● 1. 两数之和

基础&#xff1a; 1.哈希表是根据关键值进行直接访问的数据结构&#xff0c;时间复杂度是O(1)&#xff0c;也就是通过数组的索引下标&#xff0c;直接访问数组中的元素哈希表的作用就是用来快速判断一个元素是否出现在集合里。 2.常见的哈希结构&#xff1a; 数组set &#…

计算机视觉 | 交通信号灯状态的检测和识别

Hi&#xff0c;大家好&#xff0c;我是半亩花海。本项目旨在使用计算机视觉技术检测交通信号灯的状态&#xff0c;主要针对红色和绿色信号灯的识别。通过分析输入图像中的像素颜色信息&#xff0c;利用OpenCV库实现对信号灯状态的检测和识别。 目录 一、项目背景 二、项目功能…

CalcPad(2) 单位设置和绘制图表

CalcPad(2) 单位设置和绘制图表 Hi uu们&#xff0c;CalcPad用的还好吗&#xff1f;有发现一些问题吗&#xff1f; 在我的使用中&#xff0c;经常需要指定一些计算结果的符号&#xff0c;比如说我希望ADC最小分辨率的计算结果是以uV展示&#xff0c;那我们该怎么操作呢&#…

DB索引B+树SQL优化

数据库的索引就像一本书的目录&#xff0c;查数据快人一步&#xff0c;快速定位&#xff0c;精准打击&#xff01; 什么是数据库的索引&#xff1f; 官方介绍索引是帮助MySQL高效获取数据的数据结构。更通俗的说&#xff0c;数据库索引好比是一本书前面的目录&#xff0c;能加…

入坑 Node.js 1

原文&#xff1a;https://blog.iyatt.com/?p14717 前言 前面刚刚对 Spring Boot 有了个概念&#xff0c;再来学学 Node.js&#xff0c;顺便当学 JavaScript&#xff0c;为后面入前端做准备。 环境 Node.js 20.12.2 官方 API 文档&#xff1a;https://nodejs.org/docs/lat…

IBM SPSS Statistics for Mac:强大的数据分析软件

IBM SPSS Statistics for Mac是一款功能强大的数据分析软件&#xff0c;专为Mac用户设计&#xff0c;提供了一系列专业的统计分析和数据管理功能。无论是科研人员、数据分析师还是学生&#xff0c;都能从中获得高效、准确的数据分析支持。 IBM SPSS Statistics for Mac v27.0.1…

day_8题解

利用最大公约数求最小公倍数 #include<iostream> using namespace std;int gcd(int a,int b) {return b?gcd(b,a%b):a; }int main() {long long a,b;cin>>a>>b;long long ansgcd(a,b);cout<<(a*b)/ans<<endl;return 0; }排序遍历&#xff0c;记…

支持中文繁体,支持同时配置并启用飞书和Lark认证,JumpServer堡垒机v3.10.8 LTS版本发布

2024年4月22日&#xff0c;JumpServer开源堡垒机正式发布v3.10.8 LTS版本。JumpServer开源项目组将对v3.10 LTS版本提供长期的支持和优化&#xff0c;并定期迭代发布小版本。欢迎广大社区用户升级至v3.10 LTS最新版本&#xff0c;以获得更佳的使用体验。 在v3.10.8 LTS版本中&…