org.shoulder.security.code.img.ImageCodeGenerator Maven / Gradle / Ivy
The newest version!
package org.shoulder.security.code.img;
import org.shoulder.code.generator.ValidateCodeGenerator;
import org.shoulder.security.code.img.config.ImageCodeProperties;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
/**
* 默认的图片验证码生成器
* 数字与字母
*
* @author lym
*/
public class ImageCodeGenerator implements ValidateCodeGenerator, ImageValidateCodeType {
private final String[] FONT_NAMES;
/**
* 生成的字符,只允许 0-9,与大写字母,除去容易与数字产生混淆的I、O
*/
private final String[] CHARS = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H",
"J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
/**
* 系统配置
*/
private ImageCodeProperties imageCodeProperties;
public ImageCodeGenerator(ImageCodeProperties imageCodeProperties) {
FONT_NAMES = imageCodeProperties.getFonts().toArray(new String[0]);
this.imageCodeProperties = imageCodeProperties;
}
/**
* 生成验证码图片
*/
@Override
public ImageCode generate(ServletWebRequest request) {
Random random = ThreadLocalRandom.current();
// 1. 确定参数(图片宽、高,验证码长度)
int width = ServletRequestUtils.getIntParameter(request.getRequest(), "width",
imageCodeProperties.getWidth());
int height = ServletRequestUtils.getIntParameter(request.getRequest(), "height",
imageCodeProperties.getHeight());
int codeLength = imageCodeProperties.getLength();
// 生成随机验证码
StringBuilder validateCode = new StringBuilder();
for (int i = 0; i < imageCodeProperties.getLength(); i++) {
int index = random.nextInt(CHARS.length);
validateCode.append(CHARS[index]);
}
String validateCodeStr = validateCode.toString();
// 获得一个画笔、图片
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics graphics = image.getGraphics();
// 画背景,使用浅颜色
graphics.setColor(nextRandomColor(210, 250));
// 前4个参数:范围;后两个参数:圆角大小
graphics.fillRoundRect(0, 0, width, height, 0, 0);
// 干扰线,生成随机背景条纹
graphics.setColor(nextRandomColor(110, 180));
graphics.setFont(new Font("Times New Roman", Font.ITALIC, height - 10));
int interferenceLineNum = 128;
for (int i = 0; i < interferenceLineNum; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
graphics.drawLine(x, y, x + xl, y + yl);
}
// 画验证码,使用深颜色
graphics.setColor(nextRandomColor(30, 140));
for (int i = 0; i < codeLength; i++) {
final int offset = 5;
int fontSize = height - 20 + random.nextInt(10);
int rgbRandom = 3;
graphics.setFont(new Font(FONT_NAMES[random.nextInt(FONT_NAMES.length)], random.nextInt(rgbRandom), fontSize));
graphics.drawString(String.valueOf(validateCodeStr.charAt(i)), i * fontSize + offset, fontSize + random.nextInt(fontSize >> 1));
}
graphics.dispose();
// 将图片返回
return new ImageCode(image, validateCodeStr, imageCodeProperties.getEffectiveSeconds());
}
/**
* 获取随机颜色,亮度越大越接近白色,越低越接近黑色
*
* @param minLight 颜色的最低亮度
* @param maxLight 颜色的最大亮度
*/
private Color nextRandomColor(int minLight, int maxLight) {
Random random = ThreadLocalRandom.current();
int rbgMax = 255;
if (minLight < 0 || minLight > maxLight || maxLight > rbgMax) {
throw new IllegalArgumentException("no such color(min=" + minLight + ",max=" + maxLight + ")!");
}
int r = minLight + random.nextInt(maxLight - minLight);
int g = minLight + random.nextInt(maxLight - minLight);
int b = minLight + random.nextInt(maxLight - minLight);
return new Color(r, g, b);
}
/*void getFONTS(){
GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fontNames = e.getAvailableFontFamilyNames();
for (String fontName : fontNames) {
System.out.println(fontName);
}
}*/
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy