zoukankan      html  css  js  c++  java
  • 生成图形验证码

    package com.cinc.ecmpusercenter.utils;
    
    import com.cinc.ecmpusercenter.exception.BasException;
    import com.thoughtworks.xstream.core.util.Base64Encoder;
    
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.util.Random;
    
    /**
     * @Author: hhr
     * @Despriction:  图片验证码生成
     * @CreatedTime: 2019/7/30 8:58
     * @ModifyBy:
     * @ModifyTime:
     * @ModifyDespriction:
     * @Version: V1.0.0
     */
    @SuppressWarnings("AlibabaCommentsMustBeJavadocFormat")
    public class Captcha {
    
        // 图片的宽度
        private int width = 120;
        // 图片的高度
        private int height = 40;
        // 验证码字符个数
        private int codeCount = 4;
        // 验证码干扰线数
        private int lineCount = 50;
        // 验证码
        private String code = null;
        // 验证码图片Buffer
        private BufferedImage buffImg = null;
    
        private char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'M', 'N', 'P', 'Q', 'R',
                'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7', '8', '9' };
    
        // 生成随机数
        private Random random = new Random();
    
        public Captcha() {
            this.createCode();
        }
    
        /**
         * 生成图片
         * @param width 图片宽
         * @param height 图片高
         */
        public Captcha(int width, int height) {
            this.width = width;
            this.height = height;
            this.createCode();
        }
    
        /**
         * 生成图片
         * @param width 图片宽
         * @param height 图片高
         * @param codeCount 字符个数
         * @param lineCount 干扰线条数
         */
        public Captcha(int width, int height, int codeCount, int lineCount) {
            this.width = width;
            this.height = height;
            this.codeCount = codeCount;
            this.lineCount = lineCount;
            this.createCode();
        }
    
        public void createCode() {
            // 字体的高度
            int codeX = 0;
            // 每个字符的宽度
            int fontHeight = 0;
    
            fontHeight = height - 5;
            codeX = width / (codeCount + 3);
    
            // 图像buffer
            buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = buffImg.createGraphics();
    
            //将图像填充为白色,设置随机背景色
            g.setColor(this.getRandomColor(0, 50));
            g.fillRect(0, 0, width, height);
    
            //随机生成干扰线
            g.setColor(this.getRandomColor(50, 100));
            for (int i = 0; i < lineCount; i++){
                int x = random.nextInt(width);
                int y = random.nextInt(height);
                int xl = random.nextInt(width);
                int yl = random.nextInt(height);
    
                g.drawLine(x,y,xl,yl);
            }
    
            // 创建字体
            ImgFontByte imgFont = new ImgFontByte();
            Font font = imgFont.getFont(fontHeight);
            g.setFont(font);
    
            StringBuffer randomCode = new StringBuffer();
            // 随机产生验证码字符
            for (int i = 0; i < codeCount; i++) {
                String strRand = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);
                // 设置字体颜色
                g.setColor(getRandomColor(100,250));
                // 设置字体位置
                g.drawString(strRand, (i + 1) * codeX, getRandomNumber(height / 2) + 25);
    
                randomCode.append(strRand);
            }
            code = randomCode.toString();
        }
    
        /** 获取随机颜色 */
        private Color getRandomColor(int bc,int fc) {
    
            if (bc > 255){
                bc = 255;
            }
            if (fc > 255){
                fc = 255;
            }
    
            int r = getRandomNumber(fc - bc);
            int g = getRandomNumber(fc - bc);
            int b = getRandomNumber(fc - bc);
    
            return new Color(r, g, b);
        }
    
        /** 获取随机数 */
        private int getRandomNumber(int number) {
    
            return random.nextInt(number);
        }
    
        public void write(String path) throws IOException {
            OutputStream sos = new FileOutputStream(path);
            this.write(sos);
        }
    
        public void write(OutputStream sos) throws IOException {
            ImageIO.write(buffImg, "png", sos);
            sos.close();
        }
    
        public BufferedImage getBuffImg() {
            return this.buffImg;
        }
    
        public String getCode() {
            return this.code;
        }
    
        /** 字体样式类 */
        class ImgFontByte {
            public Font getFont(int fontHeight) {
                try {
                    Font baseFont = Font.createFont(Font.HANGING_BASELINE, new ByteArrayInputStream(
                            hex2byte(getFontByteStr())));
                    return baseFont.deriveFont(Font.PLAIN, fontHeight);
                } catch (Exception e) {
                    return new Font("Arial", Font.PLAIN, fontHeight);
                }
            }
    
            private byte[] hex2byte(String str) {
                if (str == null){
                    return null;
                }
    
                str = str.trim();
                int len = str.length();
                if (len == 0 || len % 2 == 1){
                    return null;
                }
    
                byte[] b = new byte[len / 2];
                try {
                    for (int i = 0; i < str.length(); i += 2) {
                        b[i / 2] = (byte) Integer.decode("0x" + str.substring(i, i + 2)).intValue();
                    }
                    return b;
                } catch (Exception e) {
                    return null;
                }
            }
    
            // 字体文件的十六进制字符串
            private String getFontByteStr() {
                //防止报字符串长度过长错误,改为从配置文件读取
                //return ReadFontByteProperties.getFontByteStr();
    
                return "宋体";
            }
        }
    
        /**
         * 验证
         * @param localCode  后台保存的验证码
         * @param upLoadCode 前台上送的验证码
         * @return
         */
        public boolean validateCode(String localCode,String upLoadCode){
    
            if (EmptyUtils.isStringEmpty(localCode) || EmptyUtils.isStringEmpty(upLoadCode)){
                throw new BasException("ERROR","验证码过期,请重试");
            }
    
            boolean flag = false;
    
            upLoadCode = upLoadCode.toUpperCase();
    
            if (localCode.equals(upLoadCode)){
                flag =  true;
            }
            return  flag;
        }
        /**
         * 对BufferedImage进行base64转码
         * @return
         * @throws IOException
         */
        public String getEncodeBase64() throws IOException{
    
            Base64Encoder encoder = new Base64Encoder();
    
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    
            ImageIO.write(buffImg, "png", outputStream);
    
            byte[] bytes = outputStream.toByteArray();
    
            String imageEncode = encoder.encode(bytes);
    
            return  imageEncode;
        }
    
    
    }
    

      

  • 相关阅读:
    老树新芽,在ES6下使用Express
    Swift3翻天覆地的改变
    NodeJs回调操作Promise化
    Node的关系型数据库ORM库:bookshelf
    基于Node的PetShop,RESTful API以及认证
    基于Node的PetShop,oauth2认证RESTful API
    Mongoose轻松搞定MongoDB,不要回调!
    Thymeleaf常用语法:表达式语法之运算符
    Thymeleaf对象的使用:日期对象
    Thymeleaf对象的使用:字符串对象
  • 原文地址:https://www.cnblogs.com/HHR-SUN/p/11362852.html
Copyright © 2011-2022 走看看