Java实现背景图片加自适应水印图片
由于每张图片的宽高比例不一致,希望使得水印在每张图上的尺寸可以跟随背景图变化,自动调整水印大小。避免每张背景的图所显示的logo水印不至于那么突兀。
一、导入所需Jar包
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.3</version> <!-- 请检查最新版本 --></dependency>
二、编写工具类
package com.example.file_handle.img_add_water_mark;import cn.hutool.core.date.DateUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import lombok.extern.slf4j.Slf4j;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;/*** @author: reshui* description: 添加水印图片工具类* DateTime:2025/4/23-15:15*/
@Slf4j
public class ImageWaterMarkUtil {/*** 文件暂存地址*/public static final String TEMP_FILE_PATH = System.getProperty("java.io.tmpdir");/*** 水印添加后文件存放地址*/private static final String WATER_MARK_FILE_PATH = TEMP_FILE_PATH + File.separator + "water_mark_after";/*** 时间格式*/public static String TIMESTAMP_FORMAT = "yyyyMMddHHmmss";/*** 水印图片url*/public static String WATER_MARK_IMG_URL = "https://profile-avatar.csdnimg.cn/128f2647a3ac408eafb94c7a6706689b_weixin_42477252.jpg!1";/*** 添加水印图片** @param originImgList 原始图片url* @param ratio 水印图片占背景图片的比例*/public static List<File> imgUrlAddWaterMarkForFileResult(List<String> originImgList, String watermarkImgFilePath, float ratio) throws Exception {String parentFormatDateTimeStamp = DateUtil.format(new Date(), TIMESTAMP_FORMAT);String imgFilePath = WATER_MARK_FILE_PATH + File.separator + parentFormatDateTimeStamp;log.info("imgFilePath:{}", imgFilePath);List<File> fileUrlList = new ArrayList<>();for (int i = 0; i < originImgList.size(); i++) {String originImg = originImgList.get(i);String leafFormatDateTimeStamp = DateUtil.format(new Date(), TIMESTAMP_FORMAT);String fileName = imgFilePath + File.separator + leafFormatDateTimeStamp + "_water_" + i + ".jpg";File file = FileUtil.touch(fileName);imgUrlAddWaterMark(originImg, watermarkImgFilePath, file, ratio);fileUrlList.add(file);}return fileUrlList;}/*** 添加水印图片** @param originImgList 原始图片url* @param ratio 水印图片占背景图片的比例*/public static List<File> imgFileAddWaterMarkForFileResult(List<String> originImgList, String watermarkImgFilePath, float ratio) throws Exception {String parentFormatDateTimeStamp = DateUtil.format(new Date(), TIMESTAMP_FORMAT);String imgFilePath = WATER_MARK_FILE_PATH + File.separator + parentFormatDateTimeStamp;log.info("imgFilePath:{}", imgFilePath);List<File> fileUrlList = new ArrayList<>();for (int i = 0; i < originImgList.size(); i++) {String originImg = originImgList.get(i);String leafFormatDateTimeStamp = DateUtil.format(new Date(), TIMESTAMP_FORMAT);String fileName = imgFilePath + File.separator + leafFormatDateTimeStamp + "_water_" + i + ".jpg";File file = FileUtil.touch(fileName);imgFileAddWaterMark(originImg, watermarkImgFilePath, file, ratio);fileUrlList.add(file);}return fileUrlList;}/*** 添加水印图片* 根据图片url** @param originalImagePath 背景图片url* @param watermarkImagePath 水印图片url* @param outPutFile 输出文件本地地址* @param ratio 水印图片占背景图片的比例*/private static void imgUrlAddWaterMark(String originalImagePath, String watermarkImagePath, File outPutFile, float ratio) throws IOException {// 读取原始图片URL url = new URL(originalImagePath);BufferedImage originalImage = ImageIO.read(url);// 读取水印图片URL watermarkImageUrl = new URL(watermarkImagePath);BufferedImage watermark = ImgUtil.read(watermarkImageUrl);imgAddWaterMark(originalImage, watermark, outPutFile, ratio);}/*** 添加水印图片* 根据图片file** @param originalImagePath 背景图片url* @param watermarkImagePath 水印图片url* @param outPutFile 输出文件本地地址* @param ratio 水印图片占背景图片的比例*/private static void imgFileAddWaterMark(String originalImagePath, String watermarkImagePath, File outPutFile, float ratio) throws IOException {// 读取原始图片BufferedImage originalImage = ImageIO.read(FileUtil.file(originalImagePath));// 读取水印图片BufferedImage watermark = ImgUtil.read(FileUtil.file(watermarkImagePath));imgAddWaterMark(originalImage, watermark, outPutFile, ratio);}/*** @param originalImage 原始图片url* @param watermark 水印图片url* @param outPutFile 输出图片路径*/private static void imgAddWaterMark(BufferedImage originalImage, BufferedImage watermark, File outPutFile, float ratio) throws IOException {// 读取原始图片int originalWidth = originalImage.getWidth();int originalHeight = originalImage.getHeight();// 读取水印图片// 计算水印新尺寸(保持原始宽高比), 水印宽度占背景图片宽度的30%int newWatermarkWidth = (int) (originalWidth * ratio);int newWatermarkHeight = (int) (watermark.getHeight() * ((float) newWatermarkWidth / watermark.getWidth()));// 缩放水印图片Image scaledWatermark = watermark.getScaledInstance(newWatermarkWidth, newWatermarkHeight, Image.SCALE_SMOOTH);// 计算水印位置(中下,留出边距)200x右移,200y下移int margin = 20;int xOffset = 0;int yOffset = (originalHeight / 2) - newWatermarkHeight / 2 - margin;ImgUtil.pressImage(originalImage,FileUtil.file(outPutFile),scaledWatermark, //水印图片xOffset, //x坐标修正值。 默认在中间,偏移量相对于中间偏移yOffset, //y坐标修正值。 默认在中间,偏移量相对于中间偏移1.0f);}// public static void main(String[] args) throws Exception {
// ArrayList<String> objects = new ArrayList<>();
// for (int i = 1; i <= 6; i++) {
// objects.add("C:\\Users\\86138\\Desktop\\xxx\\水印\\" + i + ".jpg");
// }
// addWaterMarkForFileResult(objects, "C:\\Users\\86138\\Desktop\\xxx\\水印\\water_mark_1.png", 0.3f);
// }public static void main(String[] args) throws Exception {ArrayList<String> objects = new ArrayList<>();objects.add("https://i-blog.csdnimg.cn/direct/9a914d3108114ec78d4aad04fad21fea.png"); imgUrlAddWaterMarkForFileResult(objects, WATER_MARK_IMG_URL, 0.3f);}
}