用Java语言给图片加文本水印

package com.test;

import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifDirectoryBase;
import net.coobird.thumbnailator.builders.BufferedImageBuilder;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;


public class AddWaterMark {

    public File addWatermark(List<String> strList, String path, MultipartFile file) {
        try {
            
            BufferedImage originalImage = ImageIO.read(file.getInputStream());

            
            double angle = this.getAngle(file);
            if (angle > 0) {
                //旋转图片
                originalImage = this.convertAngle(originalImage, angle);
            }
            int w = originalImage.getWidth();
            int h = originalImage.getHeight() / 3;
            // 创建水印图像
            BufferedImage fontImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = fontImage.createGraphics();
            g2d.setColor(Color.RED);
            g2d.setFont(new Font("SimSun", Font.BOLD, w / 20));
            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));

            //计算位置
            int lineX = w - g2d.getFontMetrics().stringWidth(lines[2]);
            int lingY = (h - g2d.getFontMetrics().getHeight()) / 2;
            for (String text : strList) {
                //绘制文本
                g2d.drawString(text, lineX / 2, lingY);
                // 间隔10像素
                lingY += g2d.getFontMetrics().getHeight() + 20;
            }
            // 释放Graphics2D对象的资源
            g2d.dispose();

            // 绘制图片
            for (int x = 0; x < originalImage.getWidth(); x++) {
                for (int y = h * 2; y < originalImage.getHeight(); y++) {
                    int fontY = y - h * 2;
                    originalImage.setRGB(x, y, fontImage.getRGB(x, fontY) == Color.RED.getRGB() ? fontImage.getRGB(x, fontY) : originalImage.getRGB(x, y));
                }
            }
            //临时文件
            File tempFile = new File(path);
            ImageIO.write(originalImage, "jpg", tempFile);
            return tempFile;
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage());
        }
    }


    /**
     * 旋转图片
     *
     * @param image 
     * @param var0  角度
     * @return BufferedImage
     */
    private BufferedImage convertAngle(BufferedImage image, double var0) {
        int var2 = image.getWidth();
        int var3 = image.getHeight();
        double[][] var5 = new double[][]{calculatePosition(0.0D, 0.0D, var0), calculatePosition(var2, 0.0D, var0), calculatePosition(0.0D, var3, var0), calculatePosition(var2, var3, var0)};
        double var6 = Math.min(Math.min(var5[0][0], var5[1][0]), Math.min(var5[2][0], var5[3][0]));
        double var8 = Math.max(Math.max(var5[0][0], var5[1][0]), Math.max(var5[2][0], var5[3][0]));
        double var10 = Math.min(Math.min(var5[0][1], var5[1][1]), Math.min(var5[2][1], var5[3][1]));
        double var12 = Math.max(Math.max(var5[0][1], var5[1][1]), Math.max(var5[2][1], var5[3][1]));
        int var14 = (int) Math.round(var8 - var6);
        int var15 = (int) Math.round(var12 - var10);
        BufferedImage var4 = (new BufferedImageBuilder(var14, var15, BufferedImage.TYPE_INT_RGB)).build();
        Graphics2D var16 = var4.createGraphics();
        var16.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        var16.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        double var17 = (double) var14 / 2.0D;
        double var19 = (double) var15 / 2.0D;
        var16.rotate(Math.toRadians(var0), var17, var19);
        int var21 = (int) Math.round((double) (var14 - var2) / 2.0D);
        int var22 = (int) Math.round((double) (var15 - var3) / 2.0D);
        var16.drawImage(image, var21, var22, null);
        var16.dispose();
        return var4;
    }

    /**
     * 计算位置
     *
     * @param var1
     * @param var3
     * @param var5
     * @return
     */
    private double[] calculatePosition(double var1, double var3, double var5) {
        var5 = Math.toRadians(var5);
        double var7 = Math.cos(var5) * var1 - Math.sin(var5) * var3;
        double var9 = Math.sin(var5) * var1 + Math.cos(var5) * var3;
        return new double[]{var7, var9};
    }


    /**
     * 获取旋转角度
     *
     * @param file 图片
     * @return double
     */
    private double getAngle(MultipartFile file) {
        if (file == null) {
            throw new IllegalArgumentException("File cannot be null");
        }
        try {
            Metadata metadata = ImageMetadataReader.readMetadata(file.getInputStream());
            if (metadata == null || metadata.getDirectories() == null) {
                return 0;
            }
            StringBuilder description = new StringBuilder();
            metadata.getDirectories().forEach(directory -> {
                if (directory.getTags() == null) {
                    return;
                }
                directory.getTags().stream()
                        .filter(tag -> tag.getTagType() == ExifDirectoryBase.TAG_ORIENTATION)
                        .forEach(tag -> {
                            String descriptionStr = tag.getDescription();
                            if (descriptionStr != null) {
                                description.append(descriptionStr.replaceAll(" ", ""));
                            }
                        });
            });
            if (description.length() > 0) {
                int rotateIndex = description.indexOf("Rotate");
                int cwIndex = description.indexOf("CW");
                if (rotateIndex >= 0 && cwIndex > 0 && rotateIndex < cwIndex) {
                    String angleStr = description.substring(rotateIndex + 6, cwIndex);
                    try {
                        int angel = Integer.parseInt(angleStr);
                        if (angel == 90 || angel == 180 || angel == 270) {
                            return angel;
                        } else {
                            return 0;
                        }
                    } catch (NumberFormatException e) {
                        throw new RuntimeException("Invalid number format in description: " + angleStr);
                    }
                } else {
                    return 0;
                }
            } else {
                return 0;
            }
        } catch (IOException | IllegalArgumentException | ImageProcessingException e) {
            throw new RuntimeException("Failed to read image or metadata: " + e.getMessage());
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值