java合并图片与文字
通过java来绘制海报,加载外部字体并设置样式大小与加粗、设置背景图、合并图片,下面是示例
import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;/** java 绘制海报* author xiaochi* date 2024/11/8*/
public class PosterCreatorTest{public static void main(String[] args) throws Exception {// 创建字体// Font font = new Font("微软雅黑", Font.BOLD, 36);// 外部字体String fontPath = "D:\\workspace\\demo3\\src\\main\\resources\\font\\SmileySans2.ttf";Font font = Font.createFont(Font.TRUETYPE_FONT, new File(fontPath));// 合并到图片上的文字String text = "欢迎来到我的世界";int width = 854;// 容器宽度int height = 1280;// 容器高度BufferedImage bgImage = ImageIO.read(new File("D:\\workspace\\demo3\\test1111.png"));BufferedImage combiner = combiner(width, height,null, bgImage, bgImage.getWidth(),bgImage.getHeight());Graphics2D g2d = combiner.createGraphics();// 绘制文本2(不换行)g2d.setColor(getColor("#1bdf1a"));g2d.drawString(text, 100, 100);// 释放图形上下文g2d.dispose();// 绘制文本1(换行)wrapText(combiner,text,font.deriveFont(Font.BOLD,26f),100,50,10,0,null);// 设置文本旋转45°wrapText(combiner,text,font.deriveFont(26f),500,50,combiner.getWidth(),0,null);wrapText(combiner,text,font.deriveFont(26f),500,50,combiner.getWidth(),45,"#ea6f5a");// 合并图片BufferedImage mergeImage = ImageIO.read(new File("D:\\02.png"));merge(combiner,mergeImage,100,100,100,500);try {// 保存图片到文件//ImageIO.write(image, "PNG", new File("D:\\workspace\\demo3\\poster.png"));// 输出文件流ByteArrayOutputStream out = new ByteArrayOutputStream();ImageIO.write(combiner,"png",out);byte[] bytes = out.toByteArray();out.close();FileOutputStream fileOutputStream = new FileOutputStream("D:\\workspace\\demo3\\poster333.png");fileOutputStream.write(bytes);fileOutputStream.close();} catch (Exception e) {e.printStackTrace();}}/*** 创建容器* @param combinerWidth 容器宽度* @param combinerHeight 容器高度* @param bgColor 背景色(默认白色,且背景图会覆盖背景色)* @param bgImage 背景图* @param bgImageWidth 背景图宽度* @param bgImageHeight 背景图高度* @return combiner容器*/public static BufferedImage combiner(int combinerWidth,int combinerHeight,String bgColor,BufferedImage bgImage,int bgImageWidth,int bgImageHeight){BufferedImage combiner = new BufferedImage(combinerWidth,combinerHeight, BufferedImage.TYPE_INT_ARGB);Graphics2D g2d = combiner.createGraphics();// 设置背景颜色g2d.setColor(Color.white);if (null != bgColor && !"".equals(bgColor)){g2d.setColor(getColor(bgColor));}g2d.fillRect(0, 0, combinerWidth, combinerHeight);// 添加背景图片if (null != bgImage){// 添加背景图片g2d.drawImage(bgImage,0,0,bgImageWidth,bgImageHeight,null);}// 释放图形上下文g2d.dispose();return combiner;}/*** 合并图片* @param combiner 容器* @param mergeImage 待合并的图片* @param width 待合并的图片宽度* @param height 待合并的图片高度* @param x 待合并的图片x坐标* @param y 待合并的图片y坐标*/public static void merge(BufferedImage combiner,BufferedImage mergeImage,int width,int height,int x,int y){//BufferedImage image = new BufferedImage(100,100,BufferedImage.TYPE_INT_ARGB);Graphics2D g2d = combiner.createGraphics();g2d.drawImage(mergeImage,x,y,width,height,null);g2d.dispose();}/*** 绘制文字* @param combiner 容器* @param text 文字* @param font 字体(包括大小、样式、颜色)* @param x 文字x坐标* @param y 文字y坐标* @param maxWidth 文字最大宽度(0为竖排显示)* @param rotate 旋转度数* @param color 文字颜色(如:#ffffff)*/public static void wrapText(BufferedImage combiner,String text,Font font,int x,int y,int maxWidth,double rotate,String color){Graphics2D g2d = combiner.createGraphics();//设置字体g2d.setFont(font);// 设置文字颜色if (null != color && !"".equals(color)){g2d.setColor(getColor(color));}// 抗锯齿属性g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //提升观感// 设置旋转AffineTransform at = new AffineTransform();at.rotate(Math.toRadians(rotate),x,y); // 旋转45度,旋转中心为(文字x坐标,100)g2d.setTransform(at);FontMetrics fontMetrics = g2d.getFontMetrics(font);String[] lines = splitText(text, maxWidth, fontMetrics); //实现文字自动换行int lineHeight = g2d.getFontMetrics().getHeight();int ystart = y;for (String line : lines) {g2d.drawString(line, x, ystart);ystart += lineHeight;}g2d.dispose();}/*** 获取颜色* @param color #2395439* @return*/public static Color getColor(String color) {if (color.charAt(0) == '#') {color = color.substring(1);}if (color.length() != 6) {return null;}try {int r = Integer.parseInt(color.substring(0, 2), 16);int g = Integer.parseInt(color.substring(2, 4), 16);int b = Integer.parseInt(color.substring(4), 16);return new Color(r, g, b);} catch (NumberFormatException nfe) {return null;}}/*** 切割文字* @param text* @param maxWidth* @param fontMetrics* @return*/private static String[] splitText(String text, int maxWidth, FontMetrics fontMetrics) {StringBuilder wrappedText = new StringBuilder();String[] words = text.split(""); //以每个字符做拆分,可根据实际需求做更改,下同List<String> lines = new ArrayList<>();for (String word : words) {// 检查添加新单词后是否会超过最大宽度if (wrappedText.length() > 0) {// 检查加上新单词后的总长度if (fontMetrics.stringWidth(wrappedText.toString() + word) > maxWidth) {// 如果超过最大宽度,将当前字符串添加到行列表,并开始新的一行lines.add(wrappedText.toString());wrappedText = new StringBuilder(word);} else {// 如果不超过最大宽度,添加新单词wrappedText.append(word);}} else {wrappedText.append(word);}}// 添加最后一行if (wrappedText.length() > 0) {lines.add(wrappedText.toString());}// 将行列表转换为数组return lines.toArray(new String[0]);}
}
OK了。测试效果图如下:

相关文章:
java合并图片与文字
通过java来绘制海报,加载外部字体并设置样式大小与加粗、设置背景图、合并图片,下面是示例 import javax.imageio.ImageIO; import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.…...
OpenCV快速入门
OpenCV(Open Source Computer Vision Library,开源计算机视觉库)是一个广泛应用于图像处理、计算机视觉、视频分析等领域的开源库。它不仅适用于研究人员和开发人员,还被广泛用于学术、工业和商业应用。本篇文章将帮助你快速了解 …...
ArcGIS软件之“计算面积几何”地图制作
一、消防站的泰森多边形 效果图: 二、人口调查的泰森多边形 确定后效果图: 三、人口调查的泰森多边形属性设置 确定后的效果图: 四、计算面积几何,用于求密度 先添加字段area_1,然后设置浮点型及字段属性 五…...
RHCE 第四次作业
一.搭建dns服务器能够对自定义的正向或者反向域完成数据解析查询。 1.配置环境 [rootlocalhost ~]# yum install bind [rootlocalhost ~]#systemctl stop firewalld [rootlocalhost ~]#setenforce 0 2.配置DNS主服务器 [rootlocalhost ~]# vim /etc/named.conf options { …...
【贪心算法】No.1---贪心算法(1)
文章目录 前言一、贪心算法:二、贪心算法示例:1.1 柠檬⽔找零1.2 将数组和减半的最少操作次数1.3 最⼤数1.4 摆动序列1.5 最⻓递增⼦序列1.6 递增的三元⼦序列 前言 👧个人主页:小沈YO. 😚小编介绍:欢迎来到…...
分布式光伏管理办法
随着分布式光伏项目的不断增加,传统的管理方式已经难以满足高效、精准的管理需求。光伏业务管理系统作为一种集信息化、智能化于一体的管理工具,正在逐步成为分布式光伏项目管理的重要支撑。 光伏业务管理系统通过数字化手段实现对光伏业务全流程的精细化…...
2024最新软件测试面试热点问题
🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 大厂面试热点问题 1、测试人员需要何时参加需求分析? 如果条件循序 原则上来说 是越早介入需求分析越好 因为测试人员对需求理解越深刻 对测试工…...
如何利用探商宝精准营销,抓住行业机遇——以AI技术与大数据推动企业信息精准筛选
近年来,随着人工智能与大数据技术的迅猛发展,企业的营销手段和策略发生了巨大变化。尤其是在信息爆炸的数字时代,如何有效利用这些技术在海量数据中精准找到潜在客户,已成为中小企业亟待解决的核心问题。 最近,全球人…...
嵌入式硬件电子电路设计(三)电源电路之负电源
引言:在对信号线性度放大要求非常高的应用需要使用双电源运放,比如高精度测量仪器、仪表等;那么就需要给双电源运放提供正负电源。 目录 负电源电路原理 负电源的作用 如何产生负电源 负电源能作功吗? 地的理解 负电压产生电路 BUCK电…...
数据仓库还是数据集市?这俩怎么选?
数据仓库和数据集市作为支持决策分析的两种不同方式,根据各自的特点和优势,有不同的应用场景,今天就来探讨下数据集市和数据仓库该怎么选? 一、数据集市和数据仓库对比 1、数据集市与数据仓库的关系: 1)数…...
计算机图形学 实验二 三维模型读取与控制
目录 一、实验内容 二、具体内容 (在实验2.3的基础上进行修改) 1、OFF格式三维模型文件的读取 2、三维模型的旋转动画 3、键盘鼠标的交互 4、模型的修改 三、代码 一、实验内容 读取实验提供的off格式三维模型,并对其赋色。利用鼠标和键盘的交互࿰…...
NAT网络工作原理和NAT类型
NAT基本工作流程 通常情况下,某个局域网中,只有路由器的ip是公网的,局域网中的设备都是内网ip,内网ip不具备直接与外部应用通信的能力。 处于内网的设备如何借助NAT来实现访问外网的应用? 对于开启了NAT功能的局域网…...
wget命令之Tomcat(三)
引言 Tomcat是一个开源的Java Web应用服务器,实现了多个关键的Java EE规范,包括Servlet、JSP(JavaServer Pages)、JavaWebSocket等。由于Tomcat技术先进、性能稳定且免费,它成为了许多企业和开发者的首选Web应用服务器…...
IP地址修改器 5.0 重制版
IP地址修改器是一款由 kn007 大佬编写的一个小工具,可以帮助小白用户方便的进行IP地址,网卡MAC修改等等功能,工具支持多网卡,并且支持管理导入多份配置等。 程序主要原理还是利用了WMI的Win32_NetworkAdapter、Win32_NetworkAdap…...
vscode编译s32ds工程
基本可以参考下面的文章,但是需要注意的是添加完环境变量后需要重启一下vscode。我现在已经能顺利编译。感谢原创 阿隆汽车 MBD_杂谈_使用VSCode编译s32k_vscode s32k-CSDN博客 https://blog.csdn.net/ALongAuto/article/details/134961294...
大数据专业为什么要学习Hadoop课程
在当今信息爆炸的时代,大数据成为了影响各行各业的重要因素,而Hadoop作为大数据处理的核心技术之一,自然成为大数据专业学生需要掌握的一项重要技能。本文将详细探讨大数据专业为何要学习Hadoop课程,帮助读者理解其必要性和实际应…...
Xilinx FPGA的Vivado开发流程
Xilinx FPGA 的 Vivado 开发流程主要包括以下步骤: 创建工程: 启动 Vivado 软件:双击 Vivado 图标打开软件。新建工程向导:在 Quick Start 中选择 Create Project,打开新建工程向导。设置工程信息: 工程名称…...
音频模型介绍
在处理音频数据方面,有多种模型表现出色,它们在不同的音频处理任务上有着各自的优势: 自动编码器:包括多通道变分自动编码器、自回归模型和生成对抗网络等,这些模型在音乐生成领域取得了令人印象深刻的成果。 深度生成…...
《编写沪深两市实时交易数据接收程序全攻略》
《编写沪深两市实时交易数据接收程序全攻略》 一、引言二、获取股票数据的方法(一)使用爬虫框架(二)调用股票接口(三)使用免费数据 API(四)利用 Excel 的 power query 三、数据接口及…...
一文学会easyexcel导入数据,多sheet页、字典转换【附带源码】
文章目录 前言一、业务流程二、实现1、引入easyexcel、fastjson、lombok包2、创建Json工具类3、创建自定义字典转换注解4、创建字典转换实现类5、创建数据对象类6、创建多sheet页封装对象7、创建Excel导入工具类8、创建测试类 三、接口测试1、启用项目2、使用数据导出的文件&am…...
AI大模型产品经理零基础到进阶学习路线图,非常详细收藏我这一篇就够了
AI产品经理区别于普通产品经理的地方,不止在懂得AI算法,更重要的是具有AI思维。 人工智能产品设计要以操作极度简单为标准,但是前端的简单代表后端的复杂,系统越复杂,才能越智能。 同样,人工智能的发展依…...
计算机毕业设计springboot月子中心信息管理系统 基于SpringBoot的产后护理中心数字化管理平台 Java母婴康复会所智能服务系统
计算机毕业设计springboot月子中心信息管理系统915bg9 (配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。随着现代社会生活节奏的加快与家庭结构的变化,越来越多的产妇选…...
Phi-4-mini-reasoning与IDEA集成开发:提升Java代码推理与注释生成效率
Phi-4-mini-reasoning与IDEA集成开发:提升Java代码推理与注释生成效率 1. 引言:当AI遇见Java开发 作为一名Java开发者,你是否经常遇到这样的困扰:接手一个复杂项目时,面对层层嵌套的代码逻辑感到无从下手;…...
ofa_image-caption_coco_distilled_en快速部署教程:7860端口WebUI调用全流程详解
ofa_image-caption_coco_distilled_en快速部署教程:7860端口WebUI调用全流程详解 本文介绍如何快速部署和使用ofa_image-caption_coco_distilled_en模型,这是一个专门用于为图片生成英文描述的AI系统。通过简单的Web界面,任何人都能轻松上传图…...
基于三菱PLC农田灌溉及MCGS组态智能灌溉系统说明双万字
基于三菱PLC农田灌溉 包含说明一万 和MCGS组态农田智能灌溉系统说明一万前阵子回豫东老家帮我叔打理那三亩秋月梨果园,那浇地给我整得怀疑人生——三伏天顶着三十七八度的太阳,扛着铁锹跑遍地头开电磁阀,中午热得头晕就算了,晚上还…...
Muzei故障排除大全:20个常见问题及其解决方案的完整列表
Muzei故障排除大全:20个常见问题及其解决方案的完整列表 【免费下载链接】muzei Muzei Live Wallpaper for Android 项目地址: https://gitcode.com/gh_mirrors/mu/muzei Muzei是一款优秀的Android动态壁纸应用,它能为您的手机主屏幕带来每日更新…...
【优选算法篇】拓扑排序——逻辑先后与任务依赖的终极拆解
文章目录逻辑的枷锁:在依赖网中寻找出路零、 拓扑排序:打破逻辑混乱的“秩序之光”一、 课程表 I & II:经典拓扑排序 (Medium)1.1 题目描述1.2 算法思路:依赖关系的剥离1.3 C 代码实战 (以课程表 II 为例)二、 火星词典&#…...
Phi-3-mini-4k-instruct-gguf多场景落地:客服话术优化、会议纪要提炼、周报生成实战
Phi-3-mini-4k-instruct-gguf多场景落地:客服话术优化、会议纪要提炼、周报生成实战 1. 轻量级文本生成利器介绍 Phi-3-mini-4k-instruct-gguf是微软推出的轻量级文本生成模型,特别适合处理日常办公场景中的文本任务。这个模型体积小巧但能力出众&…...
微信小程序语音交互实战:长按录制与点击播放的完整实现方案
1. 微信小程序语音交互功能概述 语音交互已经成为现代移动应用不可或缺的功能之一。在微信小程序中实现语音录制与播放,能够极大提升用户体验,特别适合社交、教育、工具类小程序。我最近在一个社交类小程序项目中实现了完整的语音交互模块,踩…...
YOLO12开源模型合规部署:离线环境+审计日志+模型版本固化方案
YOLO12开源模型合规部署:离线环境审计日志模型版本固化方案 1. 项目背景与核心价值 YOLO12作为Ultralytics在2025年推出的最新实时目标检测模型,在保持高速推理性能的同时显著提升了检测精度。其引入的注意力机制优化了特征提取网络,nano版…...
