zoukankan      html  css  js  c++  java
  • Java为图片加水印

    Java为图片加水印工具类

    一、简介

    • 使用Java在图片上加上水印,可以添加文字、图片
    • 编写一个工具类的代码优化和整理
    • 使用建造者模式提高工具类的可配置性

    二、效果图

    三、基本参数

    // +++++++++++++++ 配置参数 +++++++++++++++++++
    
    /** 文字水印内容 */
    private String fontText = null;
    /** 图片水印内容 */
    private String imgText = null;
    /** 操作的图片文件 */
    private String filePath = null;
    
    
    // +++++++++++++ 初始化一些参数 +++++++++++++++++
    
    /** 图片宽度 */
    private int width;
    /** 图片高度 */
    private int height;
    /** 画笔操作 */
    private Graphics2D graphics2D = null;
    /** 图片缓冲区 */
    private BufferedImage bufferedImage = null;
    
    
    // +++++++++++++ 自定义的水印参数 ++++++++++++++
    
    /** 文字字体 */
    private String fontName  = null;
    /** 文字样式 */
    private int fontStyle;
    /** 文字大小 */
    private int fontSize;
    /** 文字颜色 */
    private Color fontColor;
    /** 透明度 */
    private float alpha;
    /** 外框宽度 */
    private int borderWidth;
    /** 旋转高度 */
    private double angdeg;
    /** 间距 */
    private int spacing;
    /** 最后图片保存路径 */
    private String savePath = null;

    四、工具方法

    水印位置
    public static enum Position{
        /** 上左 */
        TOP_LEFT(1),
        /** 上右 */
        TOP_RIGHT(2),
        /** 下左 */
        BOTTOM_LEFT(3),
        /** 下右 */
        BOTTOM_RIGHT(4)
            ;
        public int type;
    
        Position(int type) {
            this.type = type;
        }
    
        public int getType() {
            return type;
        }
    }
    设置文字或者图片水印位置
    /**
      * @function              设置文字或者图片水印位置
      * @param position        添加水印的位置
      * @param waterWidth      添加水印的宽度
      * @param waterHeight     添加水印的高度
      * @param type            true:文字,false:图片
      * @return                int[]  x, y
      */
    private int[] setPosition (int position, int waterWidth, int waterHeight, boolean type) {
        int x = width - waterWidth;
        int y = height - waterHeight;
        switch (position) {
            case 1:
                x = type ? borderWidth : 0;
                y = type ? borderWidth : 0;
                break;
            case 2:
                y = type ? borderWidth : 0;
                break;
            case 3:
                x = type ? borderWidth : 0;
                y = type ? y - borderWidth : y;
                break;
            case 4:
            default:
                x = type ? x - borderWidth : x;
                y = type ? y - borderWidth : y;
                break;
        }
        return new int[]{x, y};
    }
    初始化参数

    初始化BufferImageGraphisc2D和目标图片的宽和高。

    /**
      * 初始化参数
      */
    private void init () {
        try {
            // 获取图片示例,并获取图片的高度,宽度
            Image img = ImageIO.read(new File(filePath));
            width = img.getWidth(null);
            height = img.getHeight(null);
            // 创建图片缓冲区
            bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            // 创建绘图工具
            graphics2D = bufferedImage.createGraphics();
            // 将原图放到缓冲区
            graphics2D.drawImage(img, 0, 0, width, height, null);
        } catch (IOException e) {
            System.out.println("文件读写异常");
            e.printStackTrace();
        }
    }
    将操作之后的图片存在磁盘

    如何没有填写保存路径,将会将原图片覆盖。

    /**
      * 将图片保存到磁盘
      */
    private void save () {
        String path = null;
        if ((savePath == null) || (savePath.equals(""))) {
            path = filePath;
        } else {
            path = savePath;
        }
        // 将缓冲区图片放到磁盘上
        try (FileOutputStream os = new FileOutputStream(path)) {
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
            encoder.encode((bufferedImage));
        } catch (IOException e) {
            System.out.println("文件读写异常");
            e.printStackTrace();
        }
    }
    设置文字水印的宽和高

    对于中英文字符宽度不一样,所以要对中英文进行不同的处理。

    /**
      * 获取文字位置
      * @param text
      * @return
      */
    private int getTextLength (String text) {
        int len = text.length();
        for (int i = 0; i < text.length(); i++) {
            String s = String.valueOf(text.charAt(i));
            if (s.getBytes().length > 1) {
                len ++;
            }
        }
        return len % 2 == 0 ? len / 2 : len / 2 + 1;
    }
    添加单个文字水印
    /**
      * 添加单个文字水印
      * @throws IOException
      * @param place
      */
    public void addFontWater(Position place) {
        init();
        // 创建文字水印的样式
        graphics2D.setFont(new Font(fontName, fontStyle, fontSize));
        // 文字颜色
        graphics2D.setColor(fontColor);
        // 获取文字位置x,y坐标
        int type = place.getType();
        int[] position = setPosition(type, fontSize * getTextLength(fontText), fontSize, true);
        int x = position[0];
        int y = position[1] + fontSize;
        // 将文字写入指定位置,并关闭画笔资源
        graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
        graphics2D.drawString(fontText, x, y);
        graphics2D.dispose();
        save();
    }
    创建那个操作句柄
    public static Builder create = new ImageWaterTool.Builder();
    建造者模式设置属性

    因为部分属性是默认,但是有些默认的属性是可以使用者自定义的,所以使用建造者进行对象属性构建是最好的。

    public class ImageWaterTool {
    
        // ++++++++ 配置参数 ++++++++++++++++
        /** 文字水印内容 */
        private String fontText = null;
        /** 图片水印内容 */
        private String imgText = null;
        /** 操作的图片文件 */
        private String filePath = null;
        // .....
    
        public ImageWaterTool(Builder builder) {
            this.fontText = builder.fontText;
            this.imgText = builder.imgText;
            this.filePath = builder.filePath;
               // ....
        }
    
        public static class Builder {
    
            // +++++++++++ 配置参数 +++++++++++++++
            /** 文字水印内容 */
            private String fontText = null;
            /** 图片水印内容 */
            private String imgText = null;
            /** 操作的图片文件 */
            private String filePath = null;
            // .....
            
    
            public Builder setFontText(String fontText) {
                this.fontText = fontText;
                return this;
            }
    
            public Builder setImgText(String imgText) {
                this.imgText = imgText;
                return this;
            }
    
            public Builder setFilePath(String filePath) {
                this.filePath = filePath;
                return this;
            }
    
            // ....
        }
    
        public static enum Position{
            // ....
        }
    
        // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    
        /**
         * @function              设置文字或者图片水印位置
         * @param position    添加水印的位置
         * @param waterWidth      添加水印的宽度
         * @param waterHeight     添加水印的高度
         * @param type            true:文字  ——  false:图片
         * @return                int[]  x, y
         */
        private int[] setPosition (int position, int waterWidth, int waterHeight, boolean type) {
            // ....
        }
    
        /**
         * 初始化参数
         */
        private void init () {
            // ....
        }
    
        /**
         * 将图片保存到磁盘
         */
        private void save () {
            // ....
        }
    
        /**
         * 获取文字位置
         * @param text
         * @return
         */
        private int getTextLength (String text) {
            // ....
        }
    
        /**
         * 添加单个文字水印
         * @throws IOException
         * @param place
         */
        public void addFontWater(Position place) {
            // ....
        }
    
        /**
         * 添加单个图片水印
         * @throws IOException
         */
        public void addPicWater (Position place) throws IOException {
            // ....
        }
    
        /**
         * 添加多个文字水印
         * @throws IOException
         */
        public void addManyFontWater () {
            // ....
        }
    
        /**
         * 添加多个图片水印
         * @throws IOException
         */
        public void addManyPicWater () throws IOException {
            // ....
        }
    
        public static Builder create = new ImageWaterTool.Builder();
    
        public static void main(String[] args) throws Exception {
            ImageWaterTool.create
                    .setFilePath("C:\Users\long\Desktop\test-1.png")
                    .setFontText("https://blog.csdn.net/yhflyl")
                    .setFontSize(30)
                    .build()
                    .addFontWater(Position.BOTTOM_RIGHT);
        }
    }
    使用
    public static void main(String[] args) throws Exception {
        ImageWaterTool.create
            // 本地文件路径
            .setFilePath("C:\Users\long\Desktop\test-1.png")
            // 添加的文字水印
            .setFontText("https://blog.csdn.net/yhflyl")
            // 文字大小
            .setFontSize(30)
            .build()
            .addFontWater(Position.BOTTOM_RIGHT);
    }

    五、完整代码

    import com.sun.image.codec.jpeg.JPEGCodec;
    import com.sun.image.codec.jpeg.JPEGImageEncoder;
    
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /**
     * @author 墨龙吟
     * @version 1.0.0
     * @ClassName ImageWaterUtil.java
     * @Email 2354713722@qq.com
     * @Description TODO   文件添加水印
     * @createTime 2019年09月09日 - 23:32
     */
    public class ImageWaterTool {
    
        // ++++++++++++++++++++++++++ 配置参数 +++++++++++++++++++++++++++++++++++++++++++++++++++
        /** 文字水印内容 */
        private String fontText = null;
        /** 图片水印内容 */
        private String imgText = null;
        /** 操作的图片文件 */
        private String filePath = null;
    
        // ++++++++++++++++++++++++++ 初始化一些参数 ++++++++++++++++++++++++++++++++++++++++++++++
        /** 图片宽度 */
        private int width;
        /** 图片高度 */
        private int height;
        /** 画笔操作 */
        private Graphics2D graphics2D = null;
        /** 图片缓冲区 */
        private BufferedImage bufferedImage = null;
    
        // +++++++++++++++++++++++++++++ 自定义的水印参数 ++++++++++++++++++++++++++++++++++++++++
        /** 文字字体 */
        private String fontName  = null;
        /** 文字样式 */
        private int fontStyle;
        /** 文字大小 */
        private int fontSize;
        /** 文字颜色 */
        private Color fontColor;
        /** 透明度 */
        private float alpha;
        /** 外框宽度 */
        private int borderWidth;
        /** 旋转高度 */
        private double angdeg;
        /** 间距 */
        private int spacing;
        /** 最后图片保存路径 */
        private String savePath = null;
    
        public ImageWaterTool(Builder builder) {
            this.fontText = builder.fontText;
            this.imgText = builder.imgText;
            this.filePath = builder.filePath;
            this.fontName = builder.fontName;
            this.fontStyle = builder.fontStyle;
            this.fontSize = builder.fontSize;
            this.fontColor = builder.fontColor;
            this.alpha = builder.alpha;
            this.borderWidth = builder.borderWidth;
            this.angdeg = builder.angdeg;
            this.spacing = builder.spacing;
            this.savePath = builder.savePath;
        }
    
        public static class Builder {
    
            // ++++++++++++++++++++++++++ 配置参数 +++++++++++++++++++++++++++++++++++++++++++++++++++
            /** 文字水印内容 */
            private String fontText = null;
            /** 图片水印内容 */
            private String imgText = null;
            /** 操作的图片文件 */
            private String filePath = null;
    
            // +++++++++++++++++++++++++++++ 自定义的水印参数 ++++++++++++++++++++++++++++++++++++++++
            /** 文字字体 */
            private String fontName = "微软雅黑";
            /** 文字样式 */
            private int fontStyle = Font.BOLD | Font.ITALIC;
            /** 文字大小 */
            private int fontSize = 30;
            /** 文字颜色 */
            private Color fontColor = Color.black;
            /** 透明度 */
            private float alpha = 0.3f;
            /** 外框宽度 */
            private int borderWidth = 20;
            /** 旋转高度 */
            private double angdeg = 30;
            /** 间距 */
            private int spacing = 200;
            /** 最后图片保存路径 */
            private String savePath = null;
    
    
            public Builder setFontText(String fontText) {
                this.fontText = fontText;
                return this;
            }
    
            public Builder setImgText(String imgText) {
                this.imgText = imgText;
                return this;
            }
    
            public Builder setFilePath(String filePath) {
                this.filePath = filePath;
                return this;
            }
    
            public Builder setFontName(String fontName) {
                this.fontName = fontName;
                return this;
            }
    
            public Builder setFontStyle(int fontStyle) {
                this.fontStyle = fontStyle;
                return this;
            }
    
            public Builder setFontSize(int fontSize) {
                this.fontSize = fontSize;
                return this;
            }
    
            public Builder setFontColor(Color fontColor) {
                this.fontColor = fontColor;
                return this;
            }
    
            public Builder setAlpha(float alpha) {
                this.alpha = alpha;
                return this;
            }
    
            public Builder setBorderWidth(int borderWidth) {
                this.borderWidth = borderWidth;
                return this;
            }
    
            public Builder setAngdeg(double angdeg) {
                this.angdeg = angdeg;
                return this;
            }
    
            public Builder setSpacing(int spacing) {
                this.spacing = spacing;
                return this;
            }
    
            public Builder setSavePath(String savePath) {
                this.savePath = savePath;
                return this;
            }
    
            public ImageWaterTool build () throws Exception {
                return new ImageWaterTool(this);
            }
        }
    
        public static enum Position{
            /** 上左 */
            TOP_LEFT(1),
            /** 上右 */
            TOP_RIGHT(2),
            /** 下左 */
            BOTTOM_LEFT(3),
            /** 下右 */
            BOTTOM_RIGHT(4)
            ;
            public int type;
    
            Position(int type) {
                this.type = type;
            }
    
            public int getType() {
                return type;
            }
        }
    
        // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    
        /**
         * @function              设置文字或者图片水印位置
         * @param position    添加水印的位置
         * @param waterWidth      添加水印的宽度
         * @param waterHeight     添加水印的高度
         * @param type            true:文字  ——  false:图片
         * @return                int[]  x, y
         */
        private int[] setPosition (int position, int waterWidth, int waterHeight, boolean type) {
            int x = width - waterWidth;
            int y = height - waterHeight;
            switch (position) {
                case 1:
                    x = type ? borderWidth : 0;
                    y = type ? borderWidth : 0;
                    break;
                case 2:
                    y = type ? borderWidth : 0;
                    break;
                case 3:
                    x = type ? borderWidth : 0;
                    y = type ? y - borderWidth : y;
                    break;
                case 4:
                default:
                    x = type ? x - borderWidth : x;
                    y = type ? y - borderWidth : y;
                    break;
            }
            return new int[]{x, y};
        }
    
        /**
         * 初始化参数
         */
        private void init () {
            try {
                // 获取图片示例,并获取图片的高度,宽度
                Image img = ImageIO.read(new File(filePath));
                width = img.getWidth(null);
                height = img.getHeight(null);
                // 创建图片缓冲区
                bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                // 创建绘图工具
                graphics2D = bufferedImage.createGraphics();
                // 将原图放到缓冲区
                graphics2D.drawImage(img, 0, 0, width, height, null);
            } catch (IOException e) {
                System.out.println("文件读写异常");
                e.printStackTrace();
            }
        }
    
        /**
         * 将图片保存到磁盘
         */
        private void save () {
            String path = null;
            if ((savePath == null) || (savePath.equals(""))) {
                path = filePath;
            } else {
                path = savePath;
            }
            // 将缓冲区图片放到磁盘上
            try (FileOutputStream os = new FileOutputStream(path)) {
                JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
                encoder.encode((bufferedImage));
            } catch (IOException e) {
                System.out.println("文件读写异常");
                e.printStackTrace();
            }
        }
    
        /**
         * 获取文字位置
         * @param text
         * @return
         */
        private int getTextLength (String text) {
            int len = text.length();
            for (int i = 0; i < text.length(); i++) {
                String s = String.valueOf(text.charAt(i));
                if (s.getBytes().length > 1) {
                    len ++;
                }
            }
            return len % 2 == 0 ? len / 2 : len / 2 + 1;
        }
    
        /**
         * 添加单个文字水印
         * @throws IOException
         * @param place
         */
        public void addFontWater(Position place) {
            init();
            // 创建文字水印的样式
            graphics2D.setFont(new Font(fontName, fontStyle, fontSize));
            // 文字颜色
            graphics2D.setColor(fontColor);
            // 获取文字位置x,y坐标
            int type = place.getType();
            int[] position = setPosition(type, fontSize * getTextLength(fontText), fontSize, true);
            int x = position[0];
            int y = position[1] + fontSize;
            // 将文字写入指定位置,并关闭画笔资源
            graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            graphics2D.drawString(fontText, x, y);
            graphics2D.dispose();
            save();
        }
    
        /**
         * 添加单个图片水印
         * @throws IOException
         */
        public void addPicWater (Position place) throws IOException {
            init();
            // 创建图片水印
            Image imageWater = ImageIO.read(new File(imgText));
            // 获取文字位置x,y坐标
            int type = place.getType();
            int[] position = setPosition(type, imageWater.getWidth(null), imageWater.getHeight(null), false);
            int x = position[0];
            int y = position[1];
            // 将文字写入指定位置,并关闭画笔资源
            graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            graphics2D.drawImage(imageWater, x, y, null);
            graphics2D.dispose();
            save();
        }
    
        /**
         * 添加多个文字水印
         * @throws IOException
         */
        public void addManyFontWater () {
            init();
            // 创建文字水印的样式
            graphics2D.setFont(new Font(fontName, fontStyle, fontSize));
            graphics2D.setColor(fontColor);
            // 获取文字宽高
            int waterWidth = fontSize * getTextLength(fontText);
            int waterHeight = fontSize;
            // 将文字写入指定位置,并关闭画笔资源
            graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            // 将文字旋转30度
            graphics2D.rotate(Math.toRadians(angdeg), width / 2, height / 2);
            // 添加多个
            int x = -width / 2;
            while (x < width * 1.5) {
                int y = -height / 2;
                while (y < height * 1.5) {
                    graphics2D.drawString(fontText, x, y);
                    y += waterHeight + spacing;
                }
                x += waterWidth + spacing;
            }
            graphics2D.dispose();
            save();
        }
    
        /**
         * 添加多个图片水印
         * @throws IOException
         */
        public void addManyPicWater () throws IOException {
            // 初始化
            init();
            // 创建图片水印
            Image imageWater = ImageIO.read(new File(imgText));
            // 获取水印图片的宽高
            int waterWidth = imageWater.getWidth(null);
            int waterHeight = imageWater.getHeight(null);
            // 将文字写入指定位置,并关闭画笔资源
            graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            // 将文字旋转30度
            graphics2D.rotate(Math.toRadians(angdeg), width / 2, height / 2);
            // 添加多个
            int x = -width / 2;
            while (x < width * 1.5) {
                int y = -height / 2;
                while (y < height * 1.5) {
                    graphics2D.drawImage(imageWater, x, y, null);
                    y += waterHeight + spacing;
                }
                x += waterWidth + spacing;
            }
            graphics2D.dispose();
            save();
        }
    
        public static Builder create = new ImageWaterTool.Builder();
    
        public static void main(String[] args) throws Exception {
            ImageWaterTool.create
                    .setFilePath("C:\Users\long\Desktop\test-1.png")
                    .setFontText("https://blog.csdn.net/yhflyl")
                    .setFontSize(30)
                    .build()
                    .addFontWater(Position.BOTTOM_RIGHT);
    
            // 多个文字水印
    //        ImageWaterTool.create
    //                // 设置水印文字
    //                .setFontText("我的小笨蛋")
    //                .setFilePath("C:\Users\long\Desktop\笨蛋1.jpg")
    //                // 设置添加水印后的图片路径
                    .setSavePath("C:\Users\long\Desktop\pic-444.png")
    //                // 设置多个文字之间的距离
    //                .setSpacing(100)
    //                .setAngdeg(150)
    //                //设置水印的透明度
    //                .setAlpha(0.2f)
    //                .build()
    //                .addManyFontWater();
            // 多个图片水印
    //        ImageWaterTool.create
    //                .setFilePath("C:\Users\long\Desktop\笨蛋.jpg")
    //                .setImgText("C:\Users\long\Desktop\logo.png")
    //                .build()
    //                .addManyPicWater();
        }
    }
    好的代码像粥一样,都是用时间熬出来的
  • 相关阅读:
    Linux服务器上监控网络带宽命令
    boost编译很慢的解决方法
    python select poll
    python SocketServer
    boost implicit_cast
    函数名 函数名取地址 区别
    STL make_heap push_heap pop_heap sort_heap
    STL: fill,fill_n,generate,generate_n
    gcc __attribute__
    Linux命令 lsof使用
  • 原文地址:https://www.cnblogs.com/jijm123/p/13874725.html
Copyright © 2011-2022 走看看