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;
    }
}
相关推荐
milk_yan1 分钟前
MinIO的安装与使用
linux·数据仓库·spring boot
程序员徐师兄1 小时前
Java 基于 SpringBoot 的校园外卖点餐平台微信小程序(附源码,部署,文档)
java·spring boot·微信小程序·校园外卖点餐·外卖点餐小程序·校园外卖点餐小程序
chengpei1472 小时前
chrome游览器JSON Formatter插件无效问题排查,FastJsonHttpMessageConverter导致Content-Type返回不正确
java·前端·chrome·spring boot·json
Q_27437851092 小时前
springboot基于微信小程序的周边游小程序
spring boot·微信小程序·小程序
计算机学姐3 小时前
基于微信小程序的民宿预订管理系统
java·vue.js·spring boot·后端·mysql·微信小程序·小程序
奈葵3 小时前
Spring Boot/MVC
java·数据库·spring boot
落霞的思绪3 小时前
Redis实战(黑马点评)——涉及session、redis存储验证码,双拦截器处理请求
spring boot·redis·缓存
liuyunshengsir4 小时前
Spring Boot 使用 Micrometer 集成 Prometheus 监控 Java 应用性能
java·spring boot·prometheus
何中应5 小时前
Spring Boot中选择性加载Bean的几种方式
java·spring boot·后端
2013crazy6 小时前
Java 基于 SpringBoot+Vue 的校园兼职平台(附源码、部署、文档)
java·vue.js·spring boot·兼职平台·校园兼职·兼职发布平台