import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class ImageUtil {

    /**
     * 给图片添加水印
     * @param originImgPath 原始图片的路径
     * @param targetImgPath 添加水印后图片的保存路径
     * @param markImgPath 水印的路径
     * @param mode 内部枚举类,用于指定水印铺设的样式,平铺,拉伸等
     * @param margin_x 水印之间的水平间距
     * @param margin_y 水印之间的垂直间距
     * @param opacity 水印透明度
     * @param markAngle 水印旋转角度,应在正负45度之间
     * @throws IOException
     */
    public static void markImage(String originImgPath,String targetImgPath,String markImgPath,int mode,int margin_x,int margin_y,float opacity,double markAngle) throws IOException {
        if(markAngle>45||markAngle<-45){
            throw new RuntimeException("旋转角度必须在正负45度之间。");
        }
        BufferedImage originImg= ImageIO.read(new File(originImgPath));
        BufferedImage markImage = ImageIO.read(new File(markImgPath));
        Graphics2D graphics = (Graphics2D) originImg.getGraphics();
        graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, opacity));
        graphics.rotate(markAngle);

        if(mode == PAINT_MODE.TILED.mode){
            int canvasHeight = originImg.getHeight();
            int canvasWidth = originImg.getWidth();
            int markHeight = markImage.getHeight();
            int markWidth = markImage.getHeight();
            int interval = markWidth+markHeight;
            for(int i=-canvasHeight;i<canvasWidth+canvasHeight;i=i+interval+margin_x){
                for(int j=-canvasWidth;j<canvasHeight+canvasWidth;j=j+interval+margin_y){
                    graphics.drawImage(markImage,i,j,markImage.getWidth(),markImage.getHeight(),null);
                }
            }
        }
        graphics.dispose();
        ImageIO.write(originImg,"png",new File(targetImgPath));
    }

    //内部枚举类
    enum PAINT_MODE{
        REGULAR(0),//常规
        TILED(1),//平铺
        STRETCHED(2);//拉伸
        private int mode;
        PAINT_MODE(int mode){
            this.mode = mode;
        }
    }

    //测试main方法
    public static void main(String[] args) {
        try {
            markImage("D:/source.png","D:/target.png","D:/mark.png",PAINT_MODE.TILED.mode,50,50,0.5f,-45);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  效果图:

      issue:1.只贴了平铺样式,拉伸只需要将水印图片的长宽设置为和源图片一样大。常规样式只需不循环遍历即可。

     2.旋转有一定的空间浪费,我本想通过三角函数计算旋转特定角度后循环的起止X,y轴位置,但是计算结果应用后并不能达到预期效果,只好给一个较大的定值。

     3.添加文字水印更为简单,只需调用graphics2D的drawString方法,并设置字体和颜色即可。希望有需求的朋友多多动手。

版权声明:本文为lvsunshine21原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/lvsunshine21/p/10223629.html