本文目录导读:

在Java中,为图片添加水印通常使用 java.awt 和 javax.imageio 包中的类,可以使用文字作为水印,也可以使用另一张图片作为水印。
下面提供两个最常用、最清晰的案例:
添加文字水印
这个例子会在图片的右下角添加一个半透明的文字水印。
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class TextWatermark {
/**
* 给图片添加文字水印
* @param sourcePath 原图片路径
* @param targetPath 输出图片路径
* @param text 水印文字
* @param alpha 透明度 (0.0 - 1.0)
* @param fontSize 字体大小
*/
public static void addTextWatermark(String sourcePath, String targetPath, String text, float alpha, int fontSize) {
try {
// 1. 读取原始图片
File sourceFile = new File(sourcePath);
BufferedImage originalImage = ImageIO.read(sourceFile);
// 2. 创建Graphics2D对象(画板)
Graphics2D g2d = (Graphics2D) originalImage.getGraphics();
// 3. 开启抗锯齿(让文字边缘平滑)
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 4. 设置水印透明度
AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
g2d.setComposite(alphaComposite);
// 5. 设置字体和颜色(颜色也可以是半透明的,但Alpha里设过了,这里用纯色即可)
g2d.setFont(new Font("宋体", Font.BOLD, fontSize));
g2d.setColor(Color.WHITE); // 白色水印
// 6. 计算文字位置(放在右下角,留出边距)
FontMetrics fontMetrics = g2d.getFontMetrics();
int textWidth = fontMetrics.stringWidth(text);
int textHeight = fontMetrics.getHeight();
int x = originalImage.getWidth() - textWidth - 20; // 右边留20像素边距
int y = originalImage.getHeight() - 10; // 底部留10像素边距
// 7. 绘制文字
g2d.drawString(text, x, y);
// 8. 释放资源
g2d.dispose();
// 9. 保存新图片
ImageIO.write(originalImage, "jpg", new File(targetPath)); // 注意:如果是PNG透明图片,请输出为png格式
System.out.println("文字水印添加成功!输出路径:" + targetPath);
} catch (IOException e) {
System.err.println("添加水印失败:" + e.getMessage());
e.printStackTrace();
}
}
public static void main(String[] args) {
// 使用示例
String sourceImage = "C:/test/input.jpg"; // 你的原图路径
String targetImage = "C:/test/output.jpg"; // 输出路径
String watermarkText = "© 我的水印";
float opacity = 0.5f; // 50%透明度
int fontSize = 36; // 字号
addTextWatermark(sourceImage, targetImage, watermarkText, opacity, fontSize);
}
}
添加图片水印(Logo)
这个例子会在原图的左上角叠加一张Logo图片,并支持调整透明度和位置。
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class ImageWatermark {
/**
* 给图片添加图片水印
* @param sourcePath 原图路径
* @param watermarkPath 水印图路径
* @param targetPath 输出路径
* @param x X坐标(距离左边像素)
* @param y Y坐标(距离顶部像素)
* @param alpha 透明度 (0.0 - 1.0)
* @param scale 缩放比例 (1.0 表示原尺寸,0.5 表示缩小一半)
*/
public static void addImageWatermark(String sourcePath, String watermarkPath, String targetPath, int x, int y, float alpha, double scale) {
try {
// 1. 读取原图和水印图
BufferedImage originalImage = ImageIO.read(new File(sourcePath));
BufferedImage watermarkImage = ImageIO.read(new File(watermarkPath));
// 2. 如果需要对水印进行缩放
if (scale != 1.0) {
int newWidth = (int) (watermarkImage.getWidth() * scale);
int newHeight = (int) (watermarkImage.getHeight() * scale);
Image scaledWatermark = watermarkImage.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);
// 将缩放后的Image转换为BufferedImage
BufferedImage temp = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D gTemp = temp.createGraphics();
gTemp.drawImage(scaledWatermark, 0, 0, null);
gTemp.dispose();
watermarkImage = temp;
}
// 3. 创建Graphics2D对象
Graphics2D g2d = (Graphics2D) originalImage.getGraphics();
// 4. 设置透明度
AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
g2d.setComposite(alphaComposite);
// 5. 在指定位置绘制水印图
g2d.drawImage(watermarkImage, x, y, null);
// 6. 释放资源
g2d.dispose();
// 7. 保存新图片
// 输出格式尽量保持原样,如果是PNG,后缀最好用.png
String format = targetPath.substring(targetPath.lastIndexOf(".") + 1);
ImageIO.write(originalImage, format, new File(targetPath));
System.out.println("图片水印添加成功!");
} catch (IOException e) {
System.err.println("添加水印失败:" + e.getMessage());
e.printStackTrace();
}
}
public static void main(String[] args) {
// 使用示例
String sourceImage = "C:/test/photo.jpg"; // 原图
String watermarkImage = "C:/test/logo.png"; // 水印图(最好是PNG,支持透明)
String targetImage = "C:/test/photo_watermarked.jpg";
// 参数:横坐标10,纵坐标10,透明度0.6,不缩放
addImageWatermark(sourceImage, watermarkImage, targetImage, 10, 10, 0.6f, 1.0);
}
}
| 关键点 | 说明 |
|---|---|
| 核心API | BufferedImage (图片对象)、Graphics2D (画笔)、AlphaComposite (透明度控制) |
| 输入输出 | 使用 ImageIO.read() 读取,ImageIO.write() 写入 |
| 格式兼容性 | 如果原图是 JPG,保存时也建议写 .jpg;如果原图有透明通道(如PNG),请务必保存为 .png 格式 |
| 抗锯齿 | 文字水印建议开启 RenderingHints.KEY_ANTIALIASING |
| 中文支持 | 使用中文字体时,确保系统有该字体(如 "宋体"、"微软雅黑"),或者用 Font.createFont() 加载外部字体 |
注意事项
- JPG格式不支持透明度:如果原图是JPG,水印的透明背景会变成白色,建议水印图片使用PNG格式。
- 大图片内存:处理超大图片时注意内存限制,可以考虑用
ImageIO的流式读取或调整JVM参数-Xmx。 - 坐标计算:为了让水印自动适应不同尺寸的图片(如右下角对齐),可以像案例一中那样动态计算
x,y。