SpringBoot实现图片添加水印

1、添加pom依赖

xml 复制代码
<dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
</dependency>

2、代码

java 复制代码
import net.coobird.thumbnailator.Thumbnails;

import javax.imageio.ImageIO;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Random;


public class WatermarkUtil {
    private static final List<String> ALLOWED_EXTENSIONS = Arrays.asList("jpg");

    public static void main(String[] args) {
        list();
    }
    public static void list() {
        String path = "F:\\picture\\";
        File file1 = new File(path);
        if (file1.exists()) {
            File path2 = new File("F:\\picture2\\");
            if(!path2.exists()) {
                path2.mkdirs();
            }
            File[] files = file1.listFiles();
            //File file2 = files[0];
            for (int i = 0;i<files.length;i++) {
                File file2 = files[i];
                //带水印版本的名字
                String watermarkName = file2.getName();
                // 创建带水印的文件对象
                //创建带水印且压缩画质的版本
                File newWatermarkName = new File(path2.getAbsolutePath()+"/" + watermarkName);
                try {
                    // 为文件添加水印并压缩
                    addWatermarkAndCompress(file2, newWatermarkName,"微信:grapro666 QQ: 3642795578");
                } catch (IOException e) {
                }
            }
        }
    }

    /**
     * 检查文件名是否允许。
     *
     * 此方法通过检查文件名的扩展名来确定文件名是否被允许。文件名必须包含至少一个点(.)
     * 以标识扩展名,并且扩展名必须在预定义的允许扩展名列表中。
     *
     * @param fileName 要检查的文件名。
     * @return 如果文件名的扩展名被允许,则返回true;否则返回false。
     */
    private Boolean isAllowed(String fileName) {
        // 检查文件名是否为空或不包含点(.)
        if(fileName == null || fileName.lastIndexOf(".") == -1){
            return false;
        }
        // 提取文件名的扩展名,并转换为小写
        String extension = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
        // 检查提取的扩展名是否在允许的扩展名列表中
        return ALLOWED_EXTENSIONS.contains(extension);
    }




    /**
     * 给图片添加水印并压缩保存。
     *
     * 此方法接收原始图片文件、目标输出文件和水印文本作为参数,它将原始图片读入,
     * 添加水印后,按照原始尺寸进行压缩,并保存到目标文件中。
     *
     * @param originalFile 原始图片文件,添加水印和压缩的基础文件。
     * @param outputFile 添加水印并压缩后的图片保存位置。
     * @param watermarkText 要添加的水印文本。
     * @throws IOException 如果读取或写入文件发生错误。
     */
    private static void addWatermarkAndCompress(File originalFile, File outputFile,String watermarkText) throws IOException {
        // 读取原始图片
        BufferedImage originalImage = ImageIO.read(originalFile);
        // 添加水印
        BufferedImage watermarkedImage = addWatermark(originalImage, watermarkText);
        // 获取原图尺寸,以保持压缩后的图片尺寸与原图相同
        // 获取原图尺寸
        int originalWidth = originalImage.getWidth();
        int originalHeight = originalImage.getHeight();

        // 使用Thumbnails.of方法对添加水印后的图片进行缩放和压缩
        // 按比例缩放并压缩
        Thumbnails.of(watermarkedImage)
                .size(originalWidth, originalHeight)
                .outputQuality(0.4) // 调整画质压缩
                .toFile(outputFile);
    }


    /**
     * 给图片添加水印。
     *
     * @param image 原始图片。
     * @param watermarkText 水印文本。
     * @return 添加了水印的图片。
     */
    private static BufferedImage addWatermark(BufferedImage image, String watermarkText) {
        // 获取原始图片的宽度和高度
        int imageWidth = image.getWidth();
        int imageHeight = image.getHeight();
        // 创建Graphics2D对象,用于在图片上绘制水印
        // 创建用于绘制水印的Graphics2D对象
        Graphics2D g2d = (Graphics2D) image.getGraphics();
        // 设置透明度,使水印呈现半透明效果
        // 设置水印的属性
        AlphaComposite alphaChannel = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.9f);
        g2d.setComposite(alphaChannel);
        // 设置水印文字颜色为灰色
        g2d.setColor(Color.GRAY);
        // 设置水印文字的字体、大小和样式
        // 使用支持中文的字体,例如SimHei(黑体)
        Font font = new Font("SimHei", Font.BOLD, 40);
        g2d.setFont(font);
        // 获取水印文字的尺寸信息
        FontMetrics fontMetrics = g2d.getFontMetrics();
        Rectangle2D rect = fontMetrics.getStringBounds(watermarkText, g2d);
        int textWidth = (int) rect.getWidth();
        int textHeight = (int) rect.getHeight();
        // 用于随机生成水印位置偏移量
        Random random = new Random();
        // 平铺方式添加水印,通过控制行间距和文字在行内的偏移,实现错落有致的布局效果
        // 平铺方式添加水印,单双行错开并随机偏移
        for (int y = 0; y < imageHeight; y += textHeight + 400) {
            // 判断当前行为偶数行还是奇数行,奇数行文字向右偏移
            boolean oddRow = (y / (textHeight + 400)) % 2 == 0;
            for (int x = oddRow ? 0 : textWidth / 2; x < imageWidth; x += textWidth + 600) {
                // 随机生成水平和垂直偏移量,使水印位置略有变化,避免整齐排列
                int xOffset = random.nextInt(200) - 100; // 随机偏移 -50 到 50 像素
                int yOffset = random.nextInt(100) - 50;  // 随机偏移 -25 到 25 像素
                // 在图片上绘制水印文字,位置略有偏移
                g2d.drawString(watermarkText, x + xOffset, y + yOffset);
            }
        }
        // 释放Graphics2D资源
        g2d.dispose();
        // 返回添加了水印的图片
        return image;
    }
}
相关推荐
小蒜学长1 小时前
“守望自然”招募志愿者环保行动网站的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端
weixin_BYSJ19872 小时前
【java项目分享】springboot阅读推荐平台10600
java·javascript·spring boot·python·django·flask·php
腾渊信息科技公司3 小时前
Spring Boot集成TDengine实战:工业时序数据存储选型与迁移方案
spring boot·后端·tdengine
zoyation3 小时前
Spring Boot集成OAuth2授权码模式的三种登录策略
java·spring boot·后端
xiaoqiMikko17 小时前
Dependabot 面板全绿,不代表你的 Tomcat 没洞
java·spring boot
摇滚侠18 小时前
SpringBoot 官网 阅读笔记 启用生产就绪功能 端点
spring boot·笔记·后端
evans在进步18 小时前
HashMap 为什么线程不安全?ConcurrentHashMap 如何解决?
java·spring boot·spring
小林敲代码77881 天前
Spring Boot 3 升级踩坑:aj-captcha 行为验证码底图加载失效
java·spring boot·后端
程序员阿明1 天前
spring boot3访问resources下的文件,使得在浏览器url中可以直接访问
java·spring boot·后端
霸道流氓气质1 天前
SpringBoot中使用OAuth2 认证与 JWT Token — 概念、原理与实践
java·spring boot·后端