Java案例如何添加图片水印?

wen java案例 76

本文目录导读:

Java案例如何添加图片水印?

  1. 案例一:添加文字水印
  2. 案例二:添加图片水印(Logo)
  3. 注意事项

在Java中,为图片添加水印通常使用 java.awtjavax.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() 加载外部字体

注意事项

  1. JPG格式不支持透明度:如果原图是JPG,水印的透明背景会变成白色,建议水印图片使用PNG格式。
  2. 大图片内存:处理超大图片时注意内存限制,可以考虑用 ImageIO 的流式读取或调整JVM参数 -Xmx
  3. 坐标计算:为了让水印自动适应不同尺寸的图片(如右下角对齐),可以像案例一中那样动态计算 x, y

抱歉,评论功能暂时关闭!