业务需要将两个图片合成,并按指定字体写入标语以及用户的经纬度,代码如下:
import cn.hutool.core.img.GraphicsUtil;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;
/**
* @author Teamo
* @date 2020/9/8
*/
public class ImageUtil {
/**
* 图片合成
*
* @param is 图片流
* @param longitudeStr 经度str,例如:东经114°305547
* @param latitudeStr 维度str,例如:北纬30°544576
* @param superscript 上标语,例如:但愿人长久
* @param subscript 下标语,例如:千里共婵娟
* @return 合成后的文件
*/
public static File pictureSynthesis(InputStream is, String longitudeStr, String latitudeStr, String superscript, String subscript) {
ClassLoader classLoader = ImageUtil.class.getClassLoader();
try (InputStream endIs = classLoader.getResourceAsStream("image/end.png");
InputStream fontIs = classLoader.getResourceAsStream("font/造字工房念真.ttf")) {
BufferedImage top = ImageIO.read(is);
BufferedImage end = ImageIO.read(Objects.requireNonNull(endIs));
if (top == null || end == null) {
return null;
}
int topHeight = top.getHeight();
int topWidth = top.getWidth();
//根据上部图片调整下部banner宽高
end = resize(end, topWidth, (int) (topWidth * 0.53D));
int endWidth = end.getWidth();
int endHeight = end.getHeight();
//注册字体写入经纬度
Font font = Font.createFont(Font.TRUETYPE_FONT, Objects.requireNonNull(fontIs));
float endFontSize = endWidth / 18.75F;
Font endFont = font.deriveFont(endFontSize);
float topFontSize = topWidth / 7F;
Font topFont = font.deriveFont(topFontSize);
GraphicsEnvironment localGraphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
localGraphicsEnvironment.registerFont(font);
Graphics2D textGraphics = localGraphicsEnvironment.createGraphics(end);
textGraphics.setFont(endFont);
textGraphics.setColor(new Color(0F, 0F, 0F, 0.5F));
textGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
textGraphics.drawString(latitudeStr, (int) (endWidth * 0.566D), (int) (endHeight * 0.82D));
textGraphics.drawString(longitudeStr, (int) (endWidth * 0.566D), (int) (endHeight * 0.82D) + endFontSize);
textGraphics.dispose();
Graphics2D graphics = localGraphicsEnvironment.createGraphics(top);
graphics.setFont(topFont);
graphics.setColor(Color.WHITE);
//将文字居中
GraphicsUtil.drawString(graphics, superscript, topFont, Color.WHITE, new Rectangle(-(int) (topWidth * 0.08D), -(int) (topHeight * 0.18D), topWidth, topHeight));
GraphicsUtil.drawString(graphics, subscript, topFont, Color.WHITE, new Rectangle((int) (topWidth * 0.05D), -(int) (topHeight * 0.08D), topWidth, topHeight));
graphics.dispose();
//合并图片
Graphics2D mergeGraphics = top.createGraphics();
mergeGraphics.drawImage(end, 0, topHeight - endHeight, endWidth, endHeight, null);
mergeGraphics.dispose();
String fileName = System.currentTimeMillis() + "_" + ThreadLocalRandom.current().nextInt(1000) + ".jpg";
Path tempDirectory = Files.createTempDirectory(null);
File outputFile = new File(tempDirectory.toString(), fileName);
ImageIO.write(top, "jpg", outputFile);
//返回上传文件路径
return outputFile;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 图片修改宽高
*
* @param img
* @param newWidth
* @param newHeight
* @return
*/
public static BufferedImage resize(BufferedImage img, int newWidth, int newHeight) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage bufferedImage = new BufferedImage(newWidth, newHeight, img.getType());
Graphics2D g = bufferedImage.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, newWidth, newHeight, 0, 0, w, h, null);
g.dispose();
return bufferedImage;
}
}
其中用到了Hutool工具类在pom文件引入如下坐标:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.2</version>
</dependency>
具体测试就不测试了,由于图片涉及到未上线的内容