简易验证码生成代码示例

package com.deroser.mybatisplustest.mybatisplustest.service.impl;

import com.deroser.mybatisplustest.mybatisplustest.service.PicService;
import com.google.common.collect.Maps;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.security.SecureRandom;
import java.util.Map;
@Service("picService")
public class PicServiceImpl implements PicService {

    //定义图片的高度
    private static final int WIDTH = 90;
    //定义图片的宽度
    private static final int HEIGHT = 25;
    //定义图片显示验证码的个数
    private static final int CODE_COUNT = 4;
    //字体高度
    private static final int FONT_HEIGHT = 18;
    //图片字母组成
    private static final char[] CODE_SEQUENCE = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M',
            'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7', '8', '9',};
    //干扰线数量
    private static final int LINE_NUMBER = 2;
    private static final String FONT_NAME = "Times New Romans";
    //偏移量
    private static final int ANCHORY = 10;
    //干扰线最大长度
    private static final int LINE_LENGTH_BOUND = 12;
    //噪点密度
    private static final float YAMP_RATE = 0.01f;
    //噪点圆心半径限度
    private static final int OVAR_BOUND = 6;


    /**
     * 生成一个map集合
     * code 为生成的验证码
     * codePic 为生成的验证码BufferdImage对象
     */
    public Map<String, Object> generateCodeAndPic() {
//        1,定义图像buffer
        BufferedImage bufferedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = bufferedImage.createGraphics();
//        2,创建一个随机数生成类
        SecureRandom random = new SecureRandom();
//        3,将图像填充为白色
        graphics.setColor(createRandomColor(220, 250, random));
//        4,设置形状宽高
        graphics.fillRect(0, 0, WIDTH, HEIGHT);
//        5,创建字体,字体的大小根据图片的高度来定
        Font font = new Font(FONT_NAME, Font.BOLD, FONT_HEIGHT);
//        6,设置字体
        graphics.setFont(font);
//        7,画边框
        graphics.setColor(Color.getHSBColor(234, 234, 234));
        graphics.drawRect(0, 0, WIDTH - 1, HEIGHT - 1);
//        8,随机产生干扰线
        createRandomLine(graphics, random, LINE_NUMBER);
//        9,随机产生噪点
        createRandomPoints(graphics,random);
//        10,随机产生字符
        StringBuffer randomCode = createRandomChars(graphics, random);
//        11,释放图形上下文
        graphics.dispose();
        Map<String,Object>map = Maps.newConcurrentMap();
//        12,存放验证码
        map.put("code",randomCode);
//        13,存放生成的验证码BufferedImage图像
        map.put("codePic",bufferedImage);

        return map;
    }

    private static StringBuffer createRandomChars(Graphics2D graphics, SecureRandom random) {
        //randomCode 用于保存随机产生的验证码,以便用户登录后进行验证
        StringBuffer randomCode = new StringBuffer();
        //随机产生codeCount数字验证码
        for (int i = 0; i < CODE_COUNT; i++) {
            //1,得到随机产生的验证码数字
            String code = String.valueOf(CODE_SEQUENCE[random.nextInt(CODE_SEQUENCE.length)]);
            //2,设置字符颜色
            graphics.setColor(new Color(50+random.nextInt(100),50+random.nextInt(100),50+random.nextInt(100)));
            //3,图片旋转
            AffineTransform affine = new AffineTransform();
            affine.setToRotation(Math.PI/9*(random.nextBoolean()?1:-1),22.5*i,12);
            graphics.setTransform(affine);
            //4,画字符
            graphics.drawString(code,(WIDTH/CODE_COUNT)*i+5,HEIGHT-5);
            //5,将产生的四个随机数组合在一起
            randomCode.append(code);
        }
        return randomCode;
    }

    private static void createRandomPoints(Graphics2D graphics, SecureRandom random) {
        //噪点颜色设置为绿色
        graphics.setColor(Color.green);
        //计算噪点数量
        int area = (int) (YAMP_RATE * WIDTH * HEIGHT);
        //打印噪点
        for (int i = 0; i < area; i++) {
            int x = random.nextInt(WIDTH);//圆心坐标x
            int y = random.nextInt(HEIGHT);//圆心坐标y
            graphics.drawOval(x,y,random.nextInt(OVAR_BOUND),random.nextInt(OVAR_BOUND));//画圈

        }
    }

    private static void createRandomLine(Graphics2D graphics, SecureRandom random, int lineNumber) {
        //设置干扰线颜色
        graphics.setColor(Color.BLACK);
        for (int i = 0; i < lineNumber; i++) {
            int x = random.nextInt(WIDTH);
            int y = random.nextInt(HEIGHT);
            int x1 = random.nextInt(LINE_LENGTH_BOUND);
            int y1 = random.nextInt(LINE_LENGTH_BOUND);
            graphics.drawLine(x, y, x + x1, y + y1);

        }
    }

    private static Color createRandomColor(int fc, int bc, SecureRandom random) {
        int f = fc;
        int b = bc;
        if (f > 255) {
            f = 255;
        }
        if (f < 1) {
            f = 1;
        }
        if (b > 255) {
            b = 255;
        }
        if (b < 1) {
            b = 1;
        }
        return new Color(f + random.nextInt(b - f), f + random.nextInt(b - f), f + random.nextInt(b - f));
    }
}
package com.deroser.mybatisplustest.mybatisplustest.controller;

import com.deroser.mybatisplustest.mybatisplustest.service.PicService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.util.Map;

@RestController
@RequestMapping(value = "/pic")
public class PicController {
    @Autowired
    private PicService picService;
    @RequestMapping(value = "/verification")
    public void getVerification(HttpServletRequest request, HttpServletResponse response){
        Map<String, Object> map = picService.generateCodeAndPic();
        try{
            ImageIO.write((RenderedImage) map.get("codePic"),"jpeg",response.getOutputStream());
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

效果如下图所示
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值