Java图片验证码简单生成

生成验证码图片主要通过Java AWT中的Graphics对象画图操作,实际操作中,Controller接口可以接收前端随机参数,并保存该参数和生成的验证码的缓存关系,当提交表单时,用于校验表单中的随机码和验证码。

下面通过单元测试简单调试验证码图片的生成。

package com.study.demo.util;

import org.junit.Test;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;


public class CaptchaCodeUtilTest {

    private Random random = new Random();
    private int width = 160;
    private int height = 80;

    @Test
    public void draw(){
    	// 获取图片验证码,可以保存至缓存中
        drawCaptchaCode(getRandomStr());
    }

    private void drawCaptchaCode(String captchaCode){
    
    	// BufferedImage是Image的一个子类,Image和BufferedImage的主要作用就是将一副图片加载到内存中。
        BufferedImage buffImg = new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB);
        // Graphics类是所有图形上下文的抽象基类,允许应用程序绘制在各种设备上实现的组件,以及屏幕上的图像
        Graphics graphics = buffImg.getGraphics();

        // 设置背景色(范围)
        int bcb = 200, bce = 255;
        graphics.setColor(getRandomColor(bcb, bce));
        graphics.fillRect(0, 0, width, height);
        // 设置干扰线
        drawLine(graphics);
        // 填充字符
        drawString(graphics, captchaCode);

        try {
        	// 输出到某个文件中
            OutputStream os = new FileOutputStream(new File("F:/Test/code.png"));
            ImageIO.write(buffImg, "png", os);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

	/**
	 * 填充字符串
	 */
    private void drawString(Graphics graphics, String captchaCode) {
        char [] chars = captchaCode.toCharArray();
        int x = 5;
        for (char aChar : chars) {
            int size = 40 + random.nextInt(30);
            Font font = getRandomFont(size);
            FontMetrics fm = sun.font.FontDesignMetrics.getMetrics(font);
            int fontWidth = fm.charWidth('A');
            graphics.setFont(getRandomFont(size));
            graphics.setColor(getRandomColor(0, 200));
            graphics.drawString(String.valueOf(aChar), x + 5, height - random.nextInt(15));
            x += fontWidth;
        }

    }

    /**
     * 设置干扰线
     * abstract void	drawLine(int x1, int y1, int x2, int y2)
     * 在该图形上下文的坐标系中的点 (x1, y1)和 (x2, y2)之间绘制一行,使用当前颜色
     */
    private void drawLine(Graphics graphics) {
        float [] lineWith = new float[]{1f,2f,3f,4f,5f};
        for (int i = 0; i < 10; i ++) {
            int y1 = 5 + random.nextInt(height - 10);
            int y2 = 5 + random.nextInt(height - 10);
            Graphics2D g2 = (Graphics2D)graphics;
            // 设置线条粗细
            g2.setStroke(new BasicStroke(lineWith[random.nextInt(lineWith.length)]));
            g2.setColor(getRandomColor(1, 255));
            g2.drawLine(0, y1, width, y2);
        }
    }

    /**
     * 获取随机颜色
     * 范围:1 - 255
     */
    private Color getRandomColor(int begin, int end){
        int r = begin + random.nextInt(end - begin);
        int g = begin + random.nextInt(end - begin);
        int b = begin + random.nextInt(end - begin);
        return new Color(r, b, g);
    }

    /**
     * 获取随机字体
     */
    private Font getRandomFont(int size) {
        List<Font> fonts = new ArrayList<>();
        fonts.add(new Font("Ravie", Font.PLAIN, size));
        fonts.add(new Font("Fixedsys", Font.PLAIN, size));
        fonts.add(new Font("Antique Olive Compact", Font.PLAIN, size));
        fonts.add(new Font("Gill Sans Ultra Bold", Font.PLAIN, size));
        fonts.add(new Font("Wide Latin", Font.PLAIN, size));
        return fonts.get(random.nextInt(fonts.size()));
    }

    /**
     * 得到随机字符
     */
    private String getRandomStr() {
        String charStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
        String randomStr = "";
        for (int i = 0; i < 4; i++) {
            int index = random.nextInt(charStr.length());
            randomStr = randomStr.concat(String.valueOf(charStr.charAt(index)));
        }
        return randomStr;
    }
}

运行单元测试后,本地生成的图片如下:
在这里插入图片描述

发布了40 篇原创文章 · 获赞 31 · 访问量 62万+

猜你喜欢

转载自blog.csdn.net/weixin_38422258/article/details/104223634