java图片验证码,不用引任何包,自己就能搞定

2023-02-03  本文已影响0人  不知不怪

1 在使用这个验证码依赖时发现里面竟然引用了servlet,springboot3大量类调整导致这个工具不能用了,

<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>
1675486770818.png

想了一下自写个图片验证码,完全没有必要引一个依赖

2 验证码工具类

package com.gzz.config;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;

public class Kaptcha {
    private static final Random RAND = new Random();
    private static final int LENGTH = 4;// 验证码位数
    private static final int SIZE = 60;// 字号
    private static final int WIDTH = 160;// 画板宽
    private static final int HEIGHT = 60;// 画板高

    private static final BufferedImage IMG = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_BGR);// 创建画板
    private static final Graphics2D GRAPH = IMG.createGraphics();// 画笔

    public static byte[] imageByte(String code) throws IOException {
        GRAPH.setColor(color());// 随机颜色
        GRAPH.fillRect(0, 0, WIDTH, HEIGHT); // 0,0,100宽度,30表示高度
        GRAPH.setColor(color());// 随机颜色
        GRAPH.setFont(font());// 随机字体-可选
        GRAPH.drawString(code, 10, 50);// 坐标10,50开始画
        GRAPH.setStroke(new BasicStroke(2f));// 画笔
        for (int i = 0; i < 6; i++) {// 干扰线-可选
            GRAPH.setColor(color());
            GRAPH.drawLine(RAND.nextInt(WIDTH), RAND.nextInt(HEIGHT), RAND.nextInt(WIDTH), RAND.nextInt(HEIGHT));// 区域内随机两个点画线
        }
        for (int i = 0; i < 20; i++) {// 干扰点-可选
            GRAPH.setColor(color());
            GRAPH.drawOval(RAND.nextInt(WIDTH), RAND.nextInt(HEIGHT), 2, 2);
        }
        ByteArrayOutputStream stream = new ByteArrayOutputStream(); // 转成字节数组
        ImageIO.write(IMG, "jpg", stream);
//      ImageIO.write(image, "jpg", new File("d:/code.jpg"));
        return stream.toByteArray();
    }

    // 纯随机字符
    public static String code() {
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < LENGTH; i++) {
            switch (RAND.nextInt(3)) {
            case 0 -> code.append((char) (RAND.nextInt(26) + 65));
            case 1 -> code.append((char) (RAND.nextInt(26) + 97));
            case 2 -> code.append(RAND.nextInt(10));
            }
        }
        return code.toString();
    }

    // 随机字体
    private static Font font() {
        Font[] fonts = { new Font("微软雅黑", Font.ITALIC, SIZE), //
                new Font("新宋体", Font.PLAIN, SIZE), //
                new Font("Microsoft YaHei Ul", Font.PLAIN, SIZE), //
                new Font("仿宋", Font.PLAIN, SIZE), //
                new Font("Cambria", Font.BOLD, SIZE) };
        return fonts[RAND.nextInt(fonts.length)];
    }

    // 随机颜色
    private static Color color() {
        return new Color(RAND.nextInt(256), RAND.nextInt(256), RAND.nextInt(256));
    }

    private static String word() {
        String words = "acdefghjkmnprstwxy34578ACEFGHJKLMNPQRSTWXY";
        return String.valueOf(words.charAt(RAND.nextInt(words.length())));
    }

    // 实现不同字符的不同颜色
    private void randomColor() {
        StringBuilder code = new StringBuilder();
        for (int i = 0, left = 10; i < 4; i++, left += 20) {
            GRAPH.setColor(color());
            GRAPH.setFont(font());
            String word = word();
            code.append(word);
            GRAPH.drawString(word, left, 25);
        }
    }

    // 实现不同字符的不同旋转角度
    private void rotate() {
        StringBuilder code = new StringBuilder();// 接收验证码的字符串
        for (int i = 0, left = 10, x = 15; i < 4; i++, left += 20, x += 20) {
            GRAPH.setColor(color());// 随机颜色
            GRAPH.setFont(font());// 随机字体
            String word = word();// 获取随机字符
            code.append(word);// 拼接到字符串string
            double th = RAND.nextInt(100) / 100.0;// 随机旋转角度
            GRAPH.rotate(th, x, 25);// 旋转一个字符
            GRAPH.drawString(word, left, 25);// 画字符串
            GRAPH.rotate(-th, x, 25);// 调回原始角度
        }
    }
}

3 Controller 调用

package com.gzz.controller;

import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.gzz.config.Kaptcha;

/**
 * @author https://www.jianshu.com/u/3bd57d5f1074
 * @date 2023-02-04 14:50:00
 */
@RestController
public class HelloController {
    Logger log = LoggerFactory.getLogger(HelloController.class);

    @RequestMapping({ "/", "index" })
    public ResponseEntity<byte[]> downCode() throws IOException {
        String code = Kaptcha.code(); // 放到缓存里
        log.info("code={}", code);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_JPEG);
        return new ResponseEntity<>(Kaptcha.imageByte(code), headers, HttpStatus.OK);
    }

}

4 页面效果

http://localhost:8080/

1675488293029.png
上一篇下一篇

猜你喜欢

热点阅读