您的位置:首页 > 汽车 > 时评 > 阿里巴巴运营要学多久_在线建网站_厦门人才网招聘_免费技能培训在哪里报名

阿里巴巴运营要学多久_在线建网站_厦门人才网招聘_免费技能培训在哪里报名

2024/10/23 23:20:49 来源:https://blog.csdn.net/Supreme_Sir/article/details/142595670  浏览:    关键词:阿里巴巴运营要学多久_在线建网站_厦门人才网招聘_免费技能培训在哪里报名
阿里巴巴运营要学多久_在线建网站_厦门人才网招聘_免费技能培训在哪里报名
前序

本周接到了新项目中的一个需求:根据给定的内容合成一张图片,需求如下:

  1. 标题自动换行,如果标题中出现英文单词时,以单词为最小单元进行换行。
  2. 如果行数超过5行省略用 … 代替。
  3. 符号是下一行首字母时,自动截留到上一行末尾。
  4. 空格为下一行开头,则删除空格,显示单词,保持内容左对齐
技术栈(JAI)

Java Advanced Imaging (JAI) 是一个用于处理图像的开源Java库。它提供了一个框架,可以用来访问各种图像源,包括本地文件系统、网络资源以及数据库等,并可以对这些图像进行转换和分析。

优点:JDK 自带内容,操作简单,不用引入新的依赖。

代码概述

本功能通过加载本地的背景图片和传入的参数进行图片的合成。主要包含了背景图、二维码插图和文本内容。其中二维码插图通过 HuTool 工具包提供生成方法。

具体代码

QrCodeImageConfig.java(二维码插图配置类)

import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;/*** 插图参数*/
@Getter
@Slf4j
public class QrCodeImageConfig {/*** 二维码内容*/private final String text;/*** 二维码宽度*/private final Integer width;/*** 二维码高度*/private final Integer height;/*** 二维码颜色*/private final Color color;/*** 二维码图片接收对象*/private final File qrCodeImgFile;/*** JAI 图片对象*/private final BufferedImage qrCodeBuffer;/*** 构造函数** @param text 二维码内容* @param width 二维码宽度* @param height 二维码高度* @param color 二维码颜色* @param qrCodeImg 二维码图片接收对象*/public QrCodeImageConfig(String text, Integer width, Integer height, Color color, File qrCodeImg) {if (StringUtils.isBlank(text) || width == null || height == null || color == null || qrCodeImg == null) {throw new IllegalArgumentException("QrCodeImageParam.QrCodeImageParam 参数异常");}this.color = color;this.width = width;this.height = height;this.text = text;this.qrCodeImgFile = qrCodeImg;try {QrConfig config = new QrConfig(width, height);config.setBackColor(color);config.setMargin(1);QrCodeUtil.generate(text, config, qrCodeImg);this.qrCodeBuffer = ImageIO.read(qrCodeImg);} catch (IOException e) {throw new RuntimeException("QrCodeImageParam.QrCodeImageParam2 二维码图片配置创建异常");}}/*** 获取图片高度*/public int getImageHeight() {return qrCodeBuffer.getHeight();}/*** 获取图片宽度*/public int getImageWidth() {return qrCodeBuffer.getWidth();}
}

TextConfig.java(文本内容配置类)

import lombok.Getter;import java.awt.*;/*** 文本内容配置*/
@Getter
public class TextConfig {/*** 文本内容*/private final String text;/*** 字体库*/private final String typeface;/*** 是否加粗*/private final Boolean boldFont;/*** 字号*/private final Integer fontSize;/*** 字体颜色*/private final Color fontColor;/*** 行间距*/private final Integer lineSpacing;/*** 字间距*/private final Integer wordSpace;/*** x轴坐标*/private final Integer x;/*** y轴坐标*/private Integer y;/*** 构造函数** @param text 文本内容* @param typeface 字体库* @param boldFont 是否加粗* @param fontSize 字号* @param fontColor 字体颜色* @param lineSpacing 行间距* @param wordSpace 字间距* @param x x轴坐标* @param y y轴坐标*/public TextConfig(String text, String typeface, Boolean boldFont, Integer fontSize, Color fontColor,Integer lineSpacing, Integer wordSpace, Integer x, Integer y) {this.text = text;this.typeface = typeface;this.boldFont = boldFont;this.fontSize = fontSize;this.fontColor = fontColor;this.lineSpacing = lineSpacing;this.wordSpace = wordSpace;this.x = x;this.y = y;}/*** 构造函数** @param text 文本内容* @param typeface 字体库* @param boldFont 是否加粗* @param fontSize 字号* @param fontColor 字体颜色* @param lineSpacing 行间距* @param wordSpace 字间距* @param x x轴坐标*/public TextConfig(String text, String typeface, Boolean boldFont, Integer fontSize, Color fontColor,Integer lineSpacing, Integer wordSpace, Integer x) {this.text = text;this.typeface = typeface;this.boldFont = boldFont;this.fontSize = fontSize;this.fontColor = fontColor;this.lineSpacing = lineSpacing;this.wordSpace = wordSpace;this.x = x;}
}

GenerateAttendanceImageUtil.java(签到图片生成工具类)

import lombok.extern.slf4j.Slf4j;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;/*** 生成签到图片工具类*/
@Slf4j
public class GenerateAttendanceImageUtil {private static int y = 0;/*** 生成签到页图片(PNG格式)** @param backgroundImage 背景图片* @param title           会议主题配置* @param dateAddress     时间地址配置* @param qrCodeImgCfg    二维码图配置* @param conferee        与会人配置* @param footer          页脚配置* @param outputFile      图片输出位置*/public static void createCompositeImage(File backgroundImage, TextConfig title, TextConfig dateAddress,QrCodeImageConfig qrCodeImgCfg, TextConfig conferee, TextConfig footer, File outputFile) {try {// 加载背景图片BufferedImage bgImgBuffer = ImageIO.read(backgroundImage);Graphics g = bgImgBuffer.getGraphics();// 插入文字准备Graphics2D g2d = (Graphics2D) g;g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);// 插入会议主题y = title.getY();drawString(title, g, g2d, bgImgBuffer.getWidth() - title.getX(), false);// 插入日期、地点y += 40;drawString(dateAddress, g, g2d, bgImgBuffer.getWidth() - dateAddress.getX(), false);// 插入二维码y = Math.max(y + 30, 310);g.drawImage(qrCodeImgCfg.getQrCodeBuffer(), (bgImgBuffer.getWidth() - qrCodeImgCfg.getWidth()) / 2, y, null);// 插入与会人y += 40 + qrCodeImgCfg.getImageHeight();drawString(conferee, g, g2d, bgImgBuffer.getWidth(), true);// 插入页脚y = bgImgBuffer.getHeight() - 40;drawString(footer, g, g2d, bgImgBuffer.getWidth(), true);g.dispose();// 将结果保存为新的图片ImageIO.write(bgImgBuffer, "png", outputFile);} catch (IOException e) {log.error(e.getMessage());} finally {if (qrCodeImgCfg.getQrCodeImgFile().exists()) {boolean delete = qrCodeImgCfg.getQrCodeImgFile().delete();if (!delete) {log.error("GenerateAttendanceImageUtil.createCompositeImage finally 二维码图片删除失败");}}}}/*** 绘制文字*/private static void drawString(TextConfig textConfig, Graphics g, Graphics2D g2d, Integer bgImgWidth, boolean horizontalCenter) {g.setFont(new Font(textConfig.getTypeface(), textConfig.getBoldFont() ? Font.BOLD : Font.PLAIN, textConfig.getFontSize()));g.setColor(textConfig.getFontColor());FontMetrics fm = g2d.getFontMetrics();int lineHeight = fm.getHeight();int x = horizontalCenter ? (bgImgWidth - fm.stringWidth(textConfig.getText())) / 2 : textConfig.getX();int lingNum = 1;for (String text : convertToArray(textConfig.getText())) {int textWidth = lingNum > 4 ? fm.stringWidth(text + "...") : fm.stringWidth(text);boolean needTrim = false;// 最多显示5行超出部分省略if (x + textWidth > bgImgWidth) {if (lingNum >= 5) {g2d.drawString("...", x, y);break;}// 符号截留在上一行,不做下一行的首字母if (!Character.isLetterOrDigit(text.charAt(0)) && !Character.isWhitespace(text.charAt(0))) {g2d.drawString(text, x, y);continue;}x = textConfig.getX();y += lineHeight + textConfig.getLineSpacing();needTrim = true;lingNum++;}// 取消换行后首字母的空格if (needTrim && text.equals(" ")) {continue;}g2d.drawString(text, x, y);x += fm.stringWidth(text) + textConfig.getWordSpace();}}/*** 判断是否为英文或数字*/private static boolean isLetterOrNumber(char c) {String character = String.valueOf(c);return Pattern.matches("[a-zA-Z0-9]", character);}/*** 将字符串拆分成最小单元*/public static String[] convertToArray(String input) {List<String> resultList = new ArrayList<>();for (int i = 0; i < input.length(); i++) {char s = input.charAt(i);if (isLetterOrNumber(s)) {StringBuilder sb = new StringBuilder();while (i < input.length() && isLetterOrNumber(input.charAt(i))) {sb.append(input.charAt(i));i++;}i--;resultList.add(sb.toString());} else {resultList.add(String.valueOf(s));}}return resultList.toArray(new String[0]);}
}

注:

  1. 工具的核心方法有两个,一是 convertToArray() 函数,我们需要通过该方法将文本内容拆分成最小单元,每一个最小单元为数组中的一个元素。换行时需要通过判断元素和本行以生成内容的长度来判断是否进行换行。
  2. 二是drawString()函数,通过该函数实现了自动换行,符号截留,首字母空格消除等功能。
  3. 该工具类由于高度耦合需求所以没有抽取成一个大家都能公用的类库大家使用,需要使用的同学请根据自己的需求进行逻辑的调整。
测试类
import java.awt.*;
import java.io.File;
import java.util.UUID;/*** 测试 生成签到二维码图片*/
public class Test {public static void main(String[] args) {File bgImg = new File("/Users/Desktop/background.png");TextConfig title = new TextConfig("aaaaaaaaaaaaaaaaa aaaaaaaaaaaa aa aaaaaaaaaa, aaaaaaaaa, aaa aaaaaaaa aaaaaaaaaaaaaaaaa aaaaaaaaaaaa aa aaaaaaaaa aaaaaaaaaa aaaaaaaaaa","Arial", true, 24, Color.BLACK, 2, 1, 24, 144);TextConfig dateAddress = new TextConfig("January 7, 2023-March 7, 2024 | Hong Kong, China", "Arial",false, 16, Color.GRAY, 2, 0, 24);QrCodeImageConfig qrCodeImgCfg = new QrCodeImageConfig("https://www.baidu.com", 200, 200,Color.WHITE, new File("/Users/Desktop/" + UUID.randomUUID() + "qrcode.png"));TextConfig conferee = new TextConfig("Hello World", "Arial", false, 30, Color.BLACK,0, 0, 24);TextConfig footer = new TextConfig("保存图片用于XXXX", "Arial", false, 14,Color.GRAY, 0, 0, 24);File outputFile = new File("/Users/Desktop/composite_image.png");GenerateAttendanceImageUtil.createCompositeImage(bgImg, title, dateAddress, qrCodeImgCfg, conferee, footer, outputFile);}
}

--------------------------------------------人生哪能多如意,万事只求半称心--------------------------------------------

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com