Java图片合成并引入外部字体写入文字

业务需要将两个图片合成,并按指定字体写入标语以及用户的经纬度,代码如下:


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>

具体测试就不测试了,由于图片涉及到未上线的内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值