JavaSE自定义验证码图片生成器

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

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


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


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


这里分享一下手动实现的生成验证码的后端功能,逻辑很简单,方便大家理解。可以在 SpringBoot项目Controller中实现调用代码,加到实际的业务逻辑中。直接复制粘贴CaptchaGenerator类,调用 getLoginCodeImage() 方法即可,用法可以参照下面的测试类。


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


(生成的验证码图片长这样:



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

相关文章
计算机中的单位换算
计算机中的单位换算
365 0
Pyside6-第十篇-纯文本QPlainTextEdit
Pyside6-第十篇-纯文本QPlainTextEdit
650 0
Pyside6-第十篇-纯文本QPlainTextEdit
Pyside6-第八篇-QLabel文本标签
Pyside6-第八篇-QLabel文本标签
530 0
|
5月前
|
Java Shell 应用服务中间件
Mac系统下配置环境变量:Javajdk、maven、tomcat 环境变量配置及对应配置文件
这篇文章介绍了如何在Mac系统下配置Java JDK、Maven和Tomcat的环境变量,包括配置文件的选择、解决环境变量在zsh shell中无效的问题、查看和设置系统环境变量的方法,以及JDK和Maven的下载、配置和测试步骤。
1932 1
Mac系统下配置环境变量:Javajdk、maven、tomcat 环境变量配置及对应配置文件
|
10月前
|
设计模式 监控 Java
Java多线程基础-11:工厂模式及代码案例之线程池(一)
本文介绍了Java并发框架中的线程池工具,特别是`java.util.concurrent`包中的`Executors`和`ThreadPoolExecutor`类。线程池通过预先创建并管理一组线程,可以提高多线程任务的效率和响应速度,减少线程创建和销毁的开销。
296 2
|
5月前
|
JavaScript
vue3,使用watch监听props中的数据
【10月更文挑战第3天】
2683 2
|
9月前
for in 和 for of的区别
for in 和 for of的区别
2651 3
|
10月前
|
编解码 安全 算法
Java多线程基础-18:线程安全的集合类与ConcurrentHashMap
如果这些单线程中的集合类确实需要在多线程中使用,该怎么办呢?思路有两个: 最直接的方式:使用锁,手动保证。如多个线程修改ArrayList对象,此时就可能有问题,就可以给修改操作进行加锁。但手动加锁的方式并不是很方便,因此标准库还提供了一些线程安全的集合类。
170 4
|
10月前
|
移动开发 分布式数据库
"二叉树的性质与推导及常见习题整理 "
这篇内容介绍了二叉树的一些性质及其推导。
245 0
|
10月前
|
存储 Go C++
【字节跳动青训营】后端笔记整理-1 | Go语言入门指南:基础语法和常用特性解析(二)
Go 语言中的复合数据类型包括数组、切片(slice)、映射(map)和结构体(struct)。
97 0