Java图片添加水印功能

图片添加水印

需求是需要添加多个斜的水印,如果只是添加单个水印可以参考这个:传送门

直接上代码:

private static void waterMarkAdd(String sourceFile,String targetFile,String watermarkText)
        throws IOException {
        File srcImgFile = new File(sourceFile);
        Image srcImg = ImageIO.read(srcImgFile);
        int srcImgWidth = srcImg.getWidth(null);
        int srcImgHeight = srcImg.getHeight(null);
        //以图片宽高中短的一边为基准长度,控制水印的大小
        int baseLength = (srcImgHeight + srcImgWidth) / 2;
        BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
        //创建画笔
        Graphics2D g = bufImg.createGraphics();
        //srcImg 为上面获取到的原始图片的图片对象
        g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
        //设置字体大小,大小根据图片尺寸变化,最小为30+文字长度
        int fontSize = Math.max(baseLength / 20, 30 + watermarkText.length());
        int textLength = g.getFontMetrics(g.getFont()).charsWidth(watermarkText.toCharArray(), 0, watermarkText.length());
        //自适应文字大小
        fontSize = (int) (fontSize - textLength * 0.2);
        int fontLength = fontSize * (watermarkText.length() + 2);
        //水印图片的宽
        int watermarkImageWidth = (int) (fontLength * 0.7);
        //水印图片的高
        int watermarkImageHeight = fontLength / 2;
        BufferedImage watermarkImage = new BufferedImage(watermarkImageWidth, watermarkImageHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D rotatedG2d = watermarkImage.createGraphics();
        //设置背景为透明
        watermarkImage = rotatedG2d.getDeviceConfiguration().createCompatibleImage(watermarkImageWidth, watermarkImageHeight, Transparency.TRANSLUCENT);
        rotatedG2d.dispose();
        //开始绘制水印文字
        rotatedG2d = watermarkImage.createGraphics();
        rotatedG2d.setFont(new Font("微软雅黑", Font.PLAIN, fontSize));
        //文字自适应图片颜色
        rotatedG2d.setColor(getMarkColor(bufImg, srcImgWidth, srcImgHeight));
        double halfWidth = watermarkImageWidth / 2.0;
        //水印文字逆时针旋转30°
        rotatedG2d.rotate(Math.toRadians(-30), halfWidth, watermarkImageHeight / 2.0);
        rotatedG2d.drawString(watermarkText, (int) (fontSize * 0.1), (int) (watermarkImageHeight / 1.75));
        rotatedG2d.dispose();
        //第一个水印的起始位置
        int startX = 0;
        int startY = (int) (-halfWidth);
        //循环添加水印
        for (int posX = startX; posX <= srcImgWidth; posX += watermarkImageWidth) {
            for (int posY = startY; posY <= srcImgHeight; posY += watermarkImageHeight) {
                //将绘制的水印文字图片画到原图片
                g.drawImage(watermarkImage, posX, posY, null);
            }
        }
        g.dispose();
        // 输出图片
        FileOutputStream outImgStream = new FileOutputStream(targetFile);
        //这里转出的格式要与原来的相同,不然图片文件会变得异常大
        String fileExtName = sourceFile.substring(souceFile.lastIndexOf(".") + 1);
        ImageIO.write(bufImg, fileExtName, outImgStream);
        System.out.println("添加水印完成");
        outImgStream.flush();
        outImgStream.close();
    }

获取水印文字颜色方法

    public static Color getMarkColor(BufferedImage bi, int w, int h) {
        long sumR = 0;
        long sumG = 0;
        long sumB = 0;
        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                Color pixel = new Color(bi.getRGB(x, y));
                sumR += pixel.getRed();
                sumG += pixel.getGreen();
                sumB += pixel.getBlue();
            }
        }
        int num = w * h;
        int markColor = (int) (sumR / num + sumG / num + sumB / num) / 3;
        int halfRgb = 128;
        if (markColor < halfRgb) {
            markColor = markColor - 50 < 0 ? markColor + 50 : markColor - 50;
        } else {
            markColor = markColor + 50 > 255 ? markColor - 50 : markColor + 50;
        }
        return new Color(markColor, markColor, markColor, 100);
    }

写一个main方法测试一下:

public static void main(String[] args) throws IOException {
        long start = System.currentTimeMillis();
        waterMarkAdd("D:/aaa.png","D:/watermark/aaa.png","我是水印");
        System.out.println(System.currentTimeMillis()-start);
    }

效果展示:
在这里插入图片描述
图片长宽1130 x 676,大小250kb,本机i5十一代笔记本处理器,耗时如下:在这里插入图片描述
大概一秒左右

这个文字大小会自适应图片大小,然后水印颜色也会自适应图片颜色,不会出现刚好图片颜色跟水印一致而看不出水印的问题

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值