美文网首页
动态生成图片验证码

动态生成图片验证码

作者: 笑叶林 | 来源:发表于2018-07-19 16:37 被阅读27次

    动态生成图片验证码

    参数设置:

    可选配置

    1. 图片的宽度(width)
    2. 图片高度(height)
    3. 图片背景颜色(bgColor)
    4. 验证码个数(textSize)

    默认值:

    width:70
    height:35
    bgColor:white
    textSize:4

    使用方式:

    DynamicGenerateImageUtil imageUtil = new DynamicGenerateImageUtil.Builder().build();
    // outputFilePath 文件输出路径
    imageUtil.output(new FileOutputStream(new File(outputFilePath)));
    
    
    package com.hzy.util;
    
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.Random;
    
    /**
     * 动态生成图片验证码
     */
    public final class DynamicGenerateImageUtil {
        /**
         * 图片宽度
         */
        private static int w = 70;
        /**
         * 图片高度
         */
        private static int h = 35;
        /**
         * 随机源
         */
        private static Random r = new Random();
        /**
         * 可选字体
         */
        private static String[] fontNames = {"宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312"};
        /**
         * 可选字符
         */
        private static String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNOPQRSTUVWXYZ";
        /**
         * 背景色
         */
        private static Color bgColor = new Color(255, 255, 255);
        /**
         * 验证码上的文本
         */
        private static String text;
    
        /**
         * 验证码的个数
         */
        private static int textSize = 4;
    
        public DynamicGenerateImageUtil(Builder builder) {
            w = builder.width > 0 ? builder.width : w;
            h = builder.height > 0 ? builder.height : h;
            bgColor = builder.bgColor;
            textSize = builder.textSize;
        }
    
        public static class Builder {
            private int textSize;
            private int width;
            private int height;
            private Color bgColor;
    
            public Builder textSize(int codeSize) {
                this.textSize = codeSize;
                return this;
            }
    
            public Builder width(int width) {
                this.width = width;
                return this;
            }
    
            public Builder height(int height) {
                this.height = height;
                return this;
            }
    
            public Builder bgColor(Color bgColor) {
                this.bgColor = bgColor;
                return this;
            }
    
            public DynamicGenerateImageUtil build() {
                return new DynamicGenerateImageUtil(this);
            }
        }
    
        /**
         * 生成随机的颜色
         *
         * @return
         */
        private static Color randomColor() {
            int red = r.nextInt(150);
            int green = r.nextInt(150);
            int blue = r.nextInt(150);
            return new Color(red, green, blue);
        }
    
        /**
         * 生成随机的字体
         *
         * @return
         */
        private static Font randomFont() {
            int index = r.nextInt(fontNames.length);
            //生成随机的字体名称
            String fontName = fontNames[index];
            //生成随机的样式:0,无样式。1,粗体。2,斜体。3,粗体+斜体
            int style = r.nextInt(4);
            //生成随机字号,24-28
            int size = r.nextInt(4) + 24;
            return new Font(fontName, style, size);
        }
    
        private static void drawLine(BufferedImage image) {
            //一共画三条
            int num = 3;
            Graphics2D g2 = (Graphics2D) image.getGraphics();
            //生成两个点的坐标.即4个点的值。
            for (int x = 0; x < num; x++) {
                int x1 = r.nextInt(w);
                int y1 = r.nextInt(h);
                int x2 = r.nextInt(w);
                int y2 = r.nextInt(h);
                g2.setStroke(new BasicStroke(1.5F));
                //干扰线是蓝色
                g2.setColor(Color.BLUE);
                g2.drawLine(x1, y1, x2, y2);
            }
        }
    
        /**
         * 随机生成一个字符
         *
         * @return
         */
        private static char randomChar() {
            int index = r.nextInt(codes.length());
            return codes.charAt(index);
        }
    
        /**
         * 创建BufferedImage
         *
         * @return
         */
        private static BufferedImage createImage() {
            BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_BGR);
            Graphics2D g2 = (Graphics2D) image.getGraphics();
            g2.setColor(bgColor);
            g2.fillRect(0, 0, w, h);
            return image;
        }
    
        /**
         * 对外提供获取验证码的方法
         */
        private static BufferedImage getImage() {
            //创建图片缓冲区
            BufferedImage image = createImage();
            //得到绘制环境
            Graphics2D g2 = (Graphics2D) image.getGraphics();
            //用来装载生成的验证码文本
            StringBuilder sb = new StringBuilder();
            //循环codeSize次,每次生成一个字符
            for (int x = 0; x < textSize; x++) {
                //随机生成一个字母
                String s = randomChar() + "";
                //把字母添加到sb中
                sb.append(s);
                //设置当前字符的x轴坐标
                float f = x * 1.0F * w / textSize;
                //设置随机字体
                g2.setFont(randomFont());
                //设置随机颜色
                g2.setColor(randomColor());
                //画图
                g2.drawString(s, f, h - 5);
            }
            //把生成的字符串赋给this.text
            text = sb.toString();
            //添加干扰线
            drawLine(image);
            return image;
        }
    
        /**
         * 返回验证码图片上的文本
         *
         * @return
         */
        public String getText() {
            return text;
        }
    
        /**
         * 保存图片到指定的数出流
         */
        public void output(OutputStream out) throws IOException {
            ImageIO.write(getImage(), "JPEG", out);
        }
    }
    
    
    

    相关文章

      网友评论

          本文标题:动态生成图片验证码

          本文链接:https://www.haomeiwen.com/subject/rgbtmftx.html