Java中图片添加水印(文字+图片水印)

10,011 阅读2分钟

这是我参与新手入门的第2篇文章

前言

有时候我们需要对用户上传的图片打上水印,就像在掘金上传的所有图片右下角都会有一个【掘金社区】。

本文将介绍如何在Java中给图片添加文字水印图片水印

一、思路分析

给图片添加水印其实就是在原有的图片上叠加上水印的内容,那么这在Java中要如何实现呢?

此处有两种方式:

  1. 利用JDK自带的 Graphics2D :从流中读取原图片后转为 BufferedImage,然后利用 BufferedImage 创建 Graphics2D绘图对象,再使用绘图对象中的API进行相应的操作
  2. 使用第三方Jar包 Thumbnailator:使用第三方Jar包还是比较简单的,在 Thumbnailator 中已有相应的API了,只需阅读官方的文档即可实现

Thumbnailator官方Github,可自行前往观看版本及官方文档

二、实现方式

文字水印

如果是文字水印的话,使用JDK自带的 Graphics2D 会比较方便。

Graphics2D实现

实现的代码如下所示:

    public void addTextWaterMark(BufferedImage targetImg, Color textColor, int fontSize, String text, String outPath) {
        try {
            int width = targetImg.getWidth(); //图片宽
            int height = targetImg.getHeight(); //图片高
            BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
            Graphics2D g = bufferedImage.createGraphics();
            g.drawImage(targetImg, 0, 0, width, height, null);
            g.setColor(textColor); //水印颜色
            g.setFont(new Font("微软雅黑", Font.ITALIC, fontSize));
            // 水印内容放置在右下角
            int x = width - (text.length() + 1) * fontSize;
            int y = height- fontSize * 2;
            g.drawString(text, x, y);
            FileOutputStream outImgStream = new FileOutputStream(outPath);
            ImageIO.write(bufferedImage, "jpg", outImgStream);
            outImgStream.flush();
            outImgStream.close();
            g.dispose();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void addTextTest() throws IOException {
        File file = new File("D:\\12.jpg");
        BufferedImage image = ImageIO.read(file);
        addTextWaterMark(image, Color.RED, 80, "测试文本水印", "D:\\13.jpg");
    }

结果

原图片如下所示:

12.jpg

添加水印后的图片(右下角):

13.jpg

图片水印

至于图片水印的话用 Thumbnailator 会方便一点,但是在这里两种方式都有呈现。

Graphics2D实现

    public void addImageWaterMark(BufferedImage targetImg, BufferedImage waterImg, String outPath) {
        try {
            int width = targetImg.getWidth(); //图片宽
            int height = targetImg.getHeight(); //图片高
            BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
            Graphics2D g = bufferedImage.createGraphics();
            g.drawImage(targetImg, 0, 0, width, height, null);
            // 水印内容放置在右下角
            int x = width - waterImg.getWidth();
            int y = height- waterImg.getHeight();
            g.drawImage(waterImg, x, y, waterImg.getWidth(), waterImg.getHeight(), null);
            FileOutputStream outImgStream = new FileOutputStream(outPath);
            ImageIO.write(bufferedImage, "jpg", outImgStream);
            outImgStream.flush();
            outImgStream.close();
            g.dispose();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @Test
    public void addImg1Test() throws IOException {
        BufferedImage image = ImageIO.read(new File("D:\\12.jpg"));
        BufferedImage waterImage = ImageIO.read(new File("D:\\mark.png"));
        addImageWaterMark(image, waterImage, "D:\\14.jpg");
    }

Thumbnailator实现

    public void addImgWaterMark(BufferedImage targetImg, BufferedImage waterImg, String outPath) {
        try {
            Thumbnails.of(targetImg)
                    .size(targetImg.getWidth(), targetImg.getHeight()) // 大小
                    .watermark(Positions.BOTTOM_RIGHT, waterImg, 1f)  // 0.5f表示透明度,最大值为1
                    .outputQuality(1)   // 图片质量,最大值为1
                    .toFile(new File(outPath));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    @Test
    public void addImg2Test() throws IOException {
        BufferedImage image = ImageIO.read(new File("D:\\12.jpg"));
        BufferedImage waterImage = ImageIO.read(new File("D:\\mark.png"));
        addImgWaterMark(image, waterImage, "D:\\15.jpg");
    }

结果

原图片及图片水印如下所示:

12.jpg

mark.png

添加图片水印后:

15.jpg

三、总结

经过上面的实操不难发现,Thumbnailator 工具类使用起来还是很方便的。正所谓前人种树后人乘凉呀!

这是我的第二篇文章,如有帮助到你,不胜荣幸!😊