首页 > 编程语言 >Java生成验证码图片

Java生成验证码图片

时间:2022-10-23 18:02:00浏览次数:68  
标签:graphics2D java sun random 验证码 生成 nextInt Java

生成验证码

/**
 * 验证码工具类
 *
 * @name: VerificationCode
 * @author: terwer
 * @date: 2022-07-17 22:21
 **/
public class VerificationCode {
    private static final String[] randomStr = {"0", "1", "2", "3", "4",
            "5", "6", "7", "8", "9", "A", "B",
            "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
            "N", "O", "P", "Q", "R",
            "S", "T", "U", "V", "W", "X", "Y", "Z"};

    /**
     * 随机生成验证码
     *
     * @return
     */
    public static Map getVerificationCode() {
        return getVerificationCodeWithStr(null);
    }

    /**
     * 利用给定的字符串生成验证码
     *
     * @param str 指定的字符串
     * @return
     */
    public static Map getVerificationCodeWithStr(String str) {
        // 设置默认生成 4个 长度的验证码
        int strLength = 4;
        char[] strArr = null;
        if (StringUtils.isNotEmpty(str)) {
            strLength = str.length();
            strArr = str.toCharArray();
        }

        // 定义验证码图片大小
        int width = 20 * strLength + 5, height = 25;
        // 在内存中创建 图像
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 为内存中要创建的图像生成画布,
        Graphics2D graphics2D = bufferedImage.createGraphics();
        // 画一个白色矩形,作为验证码背景
        graphics2D.setColor(Color.WHITE);
        // 填充
        graphics2D.fillRect(0, 0, width, height);

        // 画 100 条 灰色的 随机干扰线
        if (StringUtils.isNotEmpty(str)) {
            graphics2D.setColor(Color.WHITE);
        } else {
            graphics2D.setColor(Color.GRAY);
        }
        Random random = new Random();
        for (int i = 0; i < 100; i++) {
            graphics2D.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));
        }

        // 创建字体
        Font font = new Font("Times New Roman", Font.BOLD, 25);
        graphics2D.setFont(font);

        StringBuffer sb = new StringBuffer();
        // 取得 4 位数的 随机字符串
        for (int i = 0; i < strLength; i++) {
            // 返回一个 随机数,在 1 和 20 之间
            String randomNumber = randomStr[random.nextInt(36)];
            if (StringUtils.isNotEmpty(str)) {
                randomNumber = String.valueOf(strArr[i]);
            }

            int red = random.nextInt(255);
            int green = random.nextInt(255);
            int blue = random.nextInt(255);
            //获得一个随机红蓝绿的配合颜色
            graphics2D.setColor(new Color(red, green, blue));
            //把该数字用画笔在画布画出,并指定数字的坐标
            if (null != randomNumber) {
                graphics2D.drawString(randomNumber, 20 * i + 5, (height / 2) + 10);
                //把该数字加到缓存字符串中。用于等会生成验证码字符串set到session中用于校对
                sb.append(randomNumber);
            }
        }
        // 清除内存的图片
        bufferedImage.flush();
        // 释放资源
        graphics2D.dispose();

        // 返回结果
        Map result = new HashMap();
        result.put("imgStream", bufferedImage);
        result.put("code", str);
        return result;
    }
}

解决 alpine 镜像运行 springboot 无法获取验证码(缺少字体)的问题

问题

Caused by: java.lang.NullPointerException
	at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264)
	at sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:219)
	at sun.awt.FontConfiguration.init(FontConfiguration.java:107)
	at sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:774)
	at sun.font.SunFontManager$2.run(SunFontManager.java:431)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.font.SunFontManager.<init>(SunFontManager.java:376)
	at sun.awt.FcFontManager.<init>(FcFontManager.java:35)
	at sun.awt.X11FontManager.<init>(X11FontManager.java:57)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)

方案

FROM maven:3.6.0-jdk-8-alpine
ENV LANG en_US.UTF-8
RUN apk add --update ttf-dejavu fontconfig && rm -rf /var/cache/apk/*

参考

https://www.cnblogs.com/oukele/p/12869137.html

标签:graphics2D,java,sun,random,验证码,生成,nextInt,Java
From: https://www.cnblogs.com/tangyouwei/p/java-generate-verification-code-picture-z1it1vl.html

相关文章

  • javadoc 文档
    javadoc帮助文档书写publicclassJavaDoc{ /** *@authorxiaowen *@paramargs *@since1.0 *@throwsnull */publicstaticvoidmain(String[]args){ S......
  • JavaScript语法-算数、比较运算符、逻辑运算符
    JavaScript语法-算数运算符<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>算符运算符</title><script><!--变量3-->......
  • Qt制作图表生成器
    ​ 基于Qt中的QCharts模块制作图表生成器软件该软件可制作多种图表​多样化主题设置​保存移植便捷快速​ 输入相关数据,自动生成对应图表饼图​柱状图​......
  • Java 后端有哪些不用学的技术?
    Java经历了长时间的技术变迁,包括:JavaEE框架,从百家混战到现在Spring基本一统天下。Web开发,从标配的SSH到现在SpirngMVC+MyBatis组合。IDE,从当年如火如荼的JBuil......
  • java程序设计(part 1)
    java语言与面向程序设计java程序介绍java三大平台:javaSE/javaEE/javaMEjava运行机制:java虚拟机代码安全性检测垃圾收集机制java编译过程:源程序(.java)——>javac编译——>......
  • JavaScript语法-变量、变量typeof、一元运算符
    JavaScript语法-变量变量变量:一小块存储数据的内存空间Java语言是强类型语言,而JavaScript是弱类型语言。强类型:在开辟变量存储空间时,定义了空间将来存储的数......
  • JavaScript
    概述JavaScript简称js,用于用户与浏览器行为交互、浏览器与服务器的数据交互ECMAScriptjs的版本,是js语言的标准。例子<!DOCTYPEhtml><htmllang="en"><head><......
  • 606 Javascript_语法_与html结合方式 and 607 Javascript_语法_注释&数据类型
     Javascript_语法_与html结合方式ECMAScript:客户端脚本语言的标准1.基本语法1.与html相结合方式1、内部js;......
  • 狂神说Java面向对象
    初识面向对象面向对象和面向过程面向过程思想步骤清晰简单,第一步做什么,第二步做什么....面对过程适合处理一些较为简单的问题面向对象思想物以类聚,分类的思维模......
  • JSON 和 JavaScript 介绍与区别
    Web开发依赖于JavaScript,但什么是JSON,以及JSON与JavaScript的区别是什么?了解WEB背后的技术对于寻求创新和充分利用可用资源的团队来说非常重要。所有与WEB相关的......