创建实体类
import lombok.Data;
import java.io.Serializable;
@Data
public class VerifyVO implements Serializable {
private String verifyString;
private String verifyBase64;
private String key;
}
图形验证码生成工具
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import sun.font.FontDesignMetrics;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Random;
import java.util.UUID;
/**
* 生成图形验证码
*/
@Slf4j
public class VerifyUtil {
/**
* 随机产生数字与字母组合的字符串
* 去掉了1,0,i,o几个容易混淆的字符
*/
private static final String RAND_STRING = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
/**
* 图片默认宽
*/
private static final int WIDTH = 82;
/**
* 图片默认高
*/
private static final int HEIGHT = 24;
/**
* 随机产生字符最大和最小数量
*/
private static final int MIN_STRING_NUM = 4;
private static final int MAX_STRING_NUM = 6;
/**
* 字体大小
*/
private static final int FONT_SIZE = 20;
private static final Random RANDOM = new Random();
public static VerifyVO getRandCode(int w,int h, int num) {
//字符数量
int strNum = Math.max(MIN_STRING_NUM, num);
strNum = Math.min(MAX_STRING_NUM, strNum);
//宽度
int width = Math.max(WIDTH, w);
width = Math.max(width, strNum * FONT_SIZE);
//高度
int height = Math.max(HEIGHT, h);
//间距
int padding = (width - strNum * FONT_SIZE) / 2;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
//产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
Graphics2D graphics = image.createGraphics();
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
//背景色 纯白
graphics.setBackground(Color.WHITE);
//图片大小
graphics.fillRect(0, 0, width, height);
//文字颜色
graphics.setColor(new Color(54,141,255));
//字体
Font font = new Font("Fixedsys", Font.BOLD, 20);
graphics.setFont(font);
//字体基准信息
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
// 绘制随机字符
StringBuilder randomString = new StringBuilder();
for (int i = 0; i < strNum; i++) {
String rand = getRandomString(RANDOM.nextInt(RAND_STRING.length()));
int x = FONT_SIZE * i + padding + (FONT_SIZE - metrics.stringWidth(rand)) / 2;
//graphics.translate(RANDOM.nextInt(3), RANDOM.nextInt(3));
graphics.drawString(rand, x, metrics.getAscent());
randomString.append(rand);
}
graphics.dispose();
VerifyVO vo = new VerifyVO();
vo.setVerifyBase64(bufferedImageToBase64(image));
vo.setKey(UUID.randomUUID().toString());
vo.setVerifyString(randomString.toString());
return vo;
}
private static String bufferedImageToBase64(BufferedImage bufferedImage) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
ImageIO.write(bufferedImage, "png", stream);
Base64 base = new Base64();
String base64 = base.encodeToString(stream.toByteArray());
stream.close();
return "data:image/png;base64," + base64;
}catch (IOException e) {
throw new RuntimeException("验证码生成异常");
}
}
/**
* 获取随机的字符
*/
public static String getRandomString(int num) {
return String.valueOf(RAND_STRING.charAt(num));
}
public static void main(String[] args) {
VerifyVO randCode = VerifyUtil.getRandCode(82, 28,4);
System.out.println(randCode.getVerifyBase64());
}
}
测试
运行main方法:
复制链接到浏览器: