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

    package com.test.utils;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Main1
    {
    
        public static void main(String[] args)
        {
            String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
            FileOutputStream fos = null;
            try
            {
                File file = new File("d:\temp\aa");
                if (!file.exists())
                {
                    System.out.println("file not exists, create it ...");
                    file.mkdirs();
                }
    
                fos = new FileOutputStream(file.getPath()+"\rj2.jpg");
    
                VerifyCodeUtils.outputImage(150, 80, fos, verifyCode);
            } catch (Exception e)
            {
                e.printStackTrace();
            } finally
            {
                try
                {
                    fos.close();
                } catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
    package com.test.utils;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.awt.geom.AffineTransform;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.Arrays;
    import java.util.Random;
    import java.util.concurrent.ThreadLocalRandom;
    
    import javax.imageio.ImageIO;
    
    public class VerifyCodeUtils
    {
    
        // 使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
        private static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
    
        /**
         * 使用系统默认字符源生成验证码
         * 
         * @param verifySize
         *            验证码长度
         * @return
         */
        public static String generateVerifyCode(int verifySize)
        {
            return generateVerifyCode(verifySize, VERIFY_CODES);
        }
    
        /**
         * 使用指定源生成验证码
         * 
         * @param verifySize
         *            验证码长度
         * @param sources
         *            验证码字符源
         * @return
         */
        public static String generateVerifyCode(int verifySize, String sources)
        {
            if (sources == null || sources.length() == 0)
            {
                sources = VERIFY_CODES;
            }
            int codesLen = sources.length();
            Random rand = new Random(System.currentTimeMillis());
            StringBuilder verifyCode = new StringBuilder(verifySize);
            for (int i = 0; i < verifySize; i++)
            {
                verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1)));
            }
            return verifyCode.toString();
        }
    
        /**
         * 输出随机验证码图片流,并返回验证码值
         * 
         * @param w
         * @param h
         * @param os
         * @param verifySize
         * @return
         * @throws IOException
         */
        public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException
        {
            String verifyCode = generateVerifyCode(verifySize);
            outputImage(w, h, os, verifyCode);
            return verifyCode;
        }
    
        /**
         * 输出指定验证码图片流
         * 
         * @param w
         * @param h
         * @param os
         * @param code
         * @throws IOException
         */
        public static void outputImage(int w, int h, OutputStream os, String code) throws IOException
        {
            int verifySize = code.length();
            BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
            Random rand = new Random();
            Graphics2D g2 = image.createGraphics();
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            Color[] colors = new Color[5];
            Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN, Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA,
                    Color.ORANGE, Color.PINK, Color.YELLOW };
            float[] fractions = new float[colors.length];
            for (int i = 0; i < colors.length; i++)
            {
                colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
                fractions[i] = rand.nextFloat();
            }
            Arrays.sort(fractions);
    
            g2.setColor(Color.GRAY);// 设置边框色
            g2.fillRect(0, 0, w, h);
    
            Color c = getRandColor(200, 250);
            g2.setColor(c);// 设置背景色
            g2.fillRect(0, 2, w, h - 4);
    
            // 绘制干扰线
            Random random = new Random();
            g2.setColor(getRandColor(160, 200));// 设置线条的颜色
            for (int i = 0; i < 20; i++)
            {
                int x = random.nextInt(w - 1);
                int y = random.nextInt(h - 1);
                int xl = random.nextInt(6) + 1;
                int yl = random.nextInt(12) + 1;
                g2.drawLine(x, y, x + xl + 40, y + yl + 20);
            }
    
            // 添加噪点
            float yawpRate = 0.05f;// 噪声率
            int area = (int) (yawpRate * w * h);
            for (int i = 0; i < area; i++)
            {
                int x = random.nextInt(w);
                int y = random.nextInt(h);
                int rgb = getRandomIntColor();
                image.setRGB(x, y, rgb);
            }
    
            shear(g2, w, h, c);// 使图片扭曲
    
            g2.setColor(getRandColor(100, 160));
            int fontSize = h - 4;
            Font font = new Font("宋体", Font.ITALIC, fontSize);
            g2.setFont(font);
            char[] chars = code.toCharArray();
            for (int i = 0; i < verifySize; i++)
            {
                AffineTransform affine = new AffineTransform();
                affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1),
                        (w / verifySize) * i + fontSize / 2, h / 2);
                g2.setTransform(affine);
                g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10);
            }
    
            g2.dispose();
            ImageIO.write(image, "jpg", os);
        }
    
        private static Color getRandColor(int fc, int bc)
        {
            Random random = ThreadLocalRandom.current();
            
            if (fc > 255)
                fc = 255;
            if (bc > 255)
                bc = 255;
            int r = fc + random.nextInt(bc - fc);
            int g = fc + random.nextInt(bc - fc);
            int b = fc + random.nextInt(bc - fc);
            return new Color(r, g, b);
        }
    
        private static int getRandomIntColor()
        {
            int[] rgb = getRandomRgb();
            int color = 0;
            for (int c : rgb)
            {
                color = color << 8;
                color = color | c;
            }
            return color;
        }
    
        private static int[] getRandomRgb()
        {
            Random random = ThreadLocalRandom.current();
            int[] rgb = new int[3];
            for (int i = 0; i < 3; i++)
            {
                rgb[i] = random.nextInt(255);
            }
            return rgb;
        }
    
        private static void shear(Graphics g, int w1, int h1, Color color)
        {
            shearX(g, w1, h1, color);
            shearY(g, w1, h1, color);
        }
    
        private static void shearX(Graphics g, int w1, int h1, Color color)
        {
            Random random = ThreadLocalRandom.current();
            int period = random.nextInt(2);
    
            boolean borderGap = true;
            int frames = 1;
            int phase = random.nextInt(2);
    
            for (int i = 0; i < h1; i++)
            {
                double d = (double) (period >> 1)
                        * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);
                g.copyArea(0, i, w1, 1, (int) d, 0);
                if (borderGap)
                {
                    g.setColor(color);
                    g.drawLine((int) d, i, 0, i);
                    g.drawLine((int) d + w1, i, w1, i);
                }
            }
    
        }
    
        private static void shearY(Graphics g, int w1, int h1, Color color)
        {
            Random random = ThreadLocalRandom.current();
            int period = random.nextInt(40) + 10; // 50;
    
            boolean borderGap = true;
            int frames = 20;
            int phase = 7;
            for (int i = 0; i < w1; i++)
            {
                double d = (double) (period >> 1)
                        * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);
                g.copyArea(i, 0, 1, h1, 0, (int) d);
                if (borderGap)
                {
                    g.setColor(color);
                    g.drawLine(i, (int) d, i, 0);
                    g.drawLine(i, (int) d + h1, i, h1);
                }
            }
    
        }
    }
  • 相关阅读:
    thinkphp5 tp5 命名空间 报错 Namespace declaration statement has to be the very first statement in the script
    开启 php 错误 提示 php-fpm 重启 nginx 500错误 解决办法 wdlinux lnmp 一键包 php脚本无法解析执行
    js 设置 cookie 定时 弹出层 提示层 下次访问 不再显示 弹窗 getCookie setCookie setTimeout
    php 二维数组 转字符串 implode 方便 mysql in 查询
    nginx 重启 ps -ef|grep nginx kill -HUP 主进程号
    jquery bootstrap help-block input 表单 提示 帮助 信息
    jquery 倒计时 60秒 短信 验证码 js ajax 获取
    jQuery如何获取同一个类标签的所有的值 遍历
    linux下C语言文件操作相关函数
    gcc,gdb用法
  • 原文地址:https://www.cnblogs.com/renjing/p/verify-code.html
Copyright © 2011-2022 走看看