美文网首页JavaJava
Java生成图片验证码

Java生成图片验证码

作者: 仲冬初七 | 来源:发表于2019-12-03 16:25 被阅读0次

    Java生成图片验证码

    手动实现图片验证码生成

    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.geom.AffineTransform;
    import java.awt.image.BufferedImage;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.Arrays;
    import java.util.Random;
    
    public class VerificationCode {
    
        private static Random random = new Random(7);
    
        /**
         * 指定色系范围随机生成颜色 ,随机公式  RGB =  fc + random.nextInt(Math.abs(bc - fc))
         * @param fc
         * @param bc
         * @return
         */
        private static Color getRandColor(int fc, int bc) {
            if (fc > 255)
                fc = 255;
            if (bc > 255)
                bc = 255;
            int temp = Math.abs(bc - fc);
            int r = fc + random.nextInt(temp);
            int g = fc + random.nextInt(temp);
            int b = fc + random.nextInt(temp);
            return new Color(r, g, b);
        }
    
        /**
         * 随机生成一个颜色数值
         * @return
         */
        private static int getRandomIntColor() {
            int[] rgb = getRandomRgb();
            int color = 0;
            for (int c : rgb) {
                color = color << 8;
                color = color | c;
            }
            return color;
        }
    
        /**
         * 随机生成三原色并返回
         * @return
         */
        private static int[] getRandomRgb() {
            int[] rgb = new int[3];
            for (int i = 0; i < 3; i++) {
                rgb[i] = random.nextInt(255);
            }
            return rgb;
        }
    
        /**
         * 将图片内容扭曲
         * @param g
         * @param w1
         * @param h1
         * @param color
         */
        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) {
    
            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) {
    
            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);
                }
    
            }
    
        }
    
        /**
         * 获取验证码图片
         * @param w 图片宽度
         * @param h 图片高度
         * @param os 图片保存的流
         * @param code  验证码
         * @throws IOException
         */
        public static void getCodeImage(int w, int h, OutputStream os, String code) throws IOException {
            BufferedImage bufferedImage = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics2D = bufferedImage.createGraphics();
            graphics2D.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[random.nextInt(colorSpaces.length)];
                fractions[i] = random.nextFloat();
            }
            Arrays.sort(fractions);
    
            graphics2D.setColor(Color.GRAY);// 设置边框色
            graphics2D.fillRect(0, 0, w, h);
    
            // 随机颜色并设置背景色
            Color randColor = getRandColor(200, 250);
            graphics2D.setColor(randColor);// 设置背景色
            graphics2D.fillRect(0, 2, w, h-4);
    
            //绘制干扰线
            graphics2D.setColor(getRandColor(0, 255));// 设置线条的颜色
            for (int i = 0; i < 15; i++) {
                int x = 0;
                int y = random.nextInt(h - 1);
                int xl = w - 1;
                int yl = random.nextInt(w - 1);
                graphics2D.drawLine(x, y, xl, yl);
            }
    
            // 添加噪点
            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();
                bufferedImage.setRGB(x, y, rgb);
            }
    
            shear(graphics2D, w, h, randColor);// 使图片扭曲
    
            int verifySize = 4;
            graphics2D.setColor(getRandColor(100, 160));
            int fontSize = h-4;
            // 设置字体
            Font font = new Font("Algerian", Font.ITALIC, fontSize);
            graphics2D.setFont(font);
            char[] chars = code.toCharArray();
            for(int i = 0; i < verifySize; i++){
                AffineTransform affine = new AffineTransform();
                affine.setToRotation(Math.PI / 4 * random.nextDouble() * (random.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, h/2);
                graphics2D.setTransform(affine);
                graphics2D.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, h/2 + fontSize/2 - 10);
            }
    
            graphics2D.dispose();
            ImageIO.write(bufferedImage, "jpg", os);
        }
    
    }
    
    

    调用演示

     OutputStream os = new FileOutputStream("/home/test.jpg");
            VerificationCode.getCodeImage(90, 30, os, "anca");
    

    相关文章

      网友评论

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

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