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;
        }
    
    
    }
    

      

  • 相关阅读:
    【crontab】误删crontab及其恢复
    New Concept English there (7)
    New Concept English there (6)
    New Concept English there (5)
    New Concept English there (4)
    New Concept English there (3)
    New Concept English there (2)Typing speed exercise
    New Concept English there (1)Typing speed exercise
    New Concept English Two 34 game over
    New Concept English Two 33 94
  • 原文地址:https://www.cnblogs.com/HHR-SUN/p/11362852.html
Copyright © 2011-2022 走看看