设计项目的时候打算在原有的功能上补充验证码功能,在实现了邮箱验证码之后想着顺便把一个简单的图片验证码生成器也实现一下,用作分享。

注意,实际开发中验证码往往采用各种组件,通过导入依赖来在后端开发时使用相关功能,而不会自己手动地实现一个原生的验证码生成器。

采取组件的方式我也尝试过,在这里不作分享,感兴趣的同学可以参考这位大佬介绍的Hutool登录验证码实现-CSDN博客

这里分享一下手动实现的生成验证码的后端功能,逻辑很简单,方便大家理解。可以在 SpringBoot项目Controller中实现调用代码,加到实际的业务逻辑中。

Github:GitHub - wyd333/CaptchaTest: 自定义验证码生成器

(生成的验证码图片长这样: JavaSE自定义验证码图片生成器-LMLPHP

CaptchaGenerator

import java.awt.*;
import java.awt.image.BufferedImage;

import java.util.Random;

public class CaptchaGenerator extends CodeUtil{

    private static final int WIDTH = 200;
    private static final int HEIGHT = 50;
    private static final int FONT_SIZE = 30; //字符大小
    private String loginCode; //验证码


    /**
     * 生成验证码图片
     * @return
     */
    public BufferedImage getLoginCodeImage(){
        //验证码图片
        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = image.getGraphics();

        // 1-生成随机验证码
        loginCode = createCode();

        // 2-设置背景
        drawBackground(graphics);

        // 3-绘制验证码
        drawRands(graphics, loginCode.toCharArray());

        // 4-关闭资源
        graphics.dispose();

        return image;
    }

    private static void drawRands(Graphics g, char[] rands) {
        g.setFont(new Font("Console", Font.BOLD, FONT_SIZE));
        for (int i = 0; i < rands.length; i++) {
            g.setColor(getRandomColor());
            g.drawString("" + rands[i], i * FONT_SIZE + 10, 30);
        }
    }


    /**
     * 生成 CODE_LENGTH 长度的随机验证码
     * @return
     */
    @Override
    public String createCode() {
        // 可以包含在验证码中的字符集合
        String charset = "0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        Random random = new Random();
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < CODE_LENGTH; i++) {
            int randomIndex = random.nextInt(charset.length());
            code.append(charset.charAt(randomIndex));
        }
        return code.toString();
    }

    /**
     * 获取随机颜色给验证码文本
     * @return 随机颜色
     */
    private static Color getRandomColor() {
        Random ran = new Random();
        return new Color(ran.nextInt(220), ran.nextInt(220), ran.nextInt(220));
    }

    /**
     * 绘制验证码图片背景
     * @param g 图片对象
     */
    private static void drawBackground(Graphics g) {
        g.setColor(Color.white);
        g.fillRect(0, 0, WIDTH, HEIGHT);

        // 绘制验证码干扰点
        for (int i = 0; i < 200; i++) {
            int x = (int) (Math.random() * WIDTH);
            int y = (int) (Math.random() * HEIGHT);
            g.setColor(getRandomColor());
            g.drawOval(x, y, 1, 1);
        }
    }

    public String getLoginCode() {
        return loginCode;
    }

}

测试类:生成5张验证码图片并保存

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * Description: 测试:生成5张验证码图片并保存
 */
public class Main {
    public static void main(String[] args) {
        int i = 5;
        while(i > 0) {
            CaptchaGenerator captchaGenerator = new CaptchaGenerator();
            BufferedImage image = captchaGenerator.getLoginCodeImage();
            // 保存图片到文件
            try {
                File output = new File("captcha" + i + ".png");
                ImageIO.write(image, "png", output);
            } catch (IOException e) {
                e.printStackTrace();
            }
            i--;
        }
    }

}
12-03 06:23