mirror of
https://github.com/dromara/tianai-captcha.git
synced 2026-05-07 14:13:05 +08:00
U 优化点选验证码,用于将来支持语序验证码等相关具有联想的点击类验证码
This commit is contained in:
+36
-21
@@ -31,7 +31,6 @@ public abstract class AbstractClickImageCaptchaGenerator extends AbstractImageCa
|
||||
@Setter
|
||||
protected Integer interferenceCount = 2;
|
||||
|
||||
|
||||
public AbstractClickImageCaptchaGenerator(ImageCaptchaResourceManager imageCaptchaResourceManager) {
|
||||
super(imageCaptchaResourceManager);
|
||||
}
|
||||
@@ -53,9 +52,13 @@ public abstract class AbstractClickImageCaptchaGenerator extends AbstractImageCa
|
||||
List<ClickImageCheckDefinition> clickImageCheckDefinitionList = new ArrayList<>(interferenceCount);
|
||||
int allImages = interferenceCount + checkClickCount;
|
||||
int avg = bgImage.getWidth() / allImages;
|
||||
List<String> imgTips = randomGetClickImgTips(allImages);
|
||||
if (allImages < imgTips.size()) {
|
||||
throw new IllegalStateException("随机生成点击图片小于请求数量, 请求生成数量=" + allImages + ",实际生成数量=" + imgTips.size());
|
||||
}
|
||||
for (int i = 0; i < allImages; i++) {
|
||||
// 随机获取点击图片
|
||||
ImgWrapper imgWrapper = randomGetClickImg();
|
||||
ImgWrapper imgWrapper = getClickImg(imgTips.get(i));
|
||||
BufferedImage image = imgWrapper.getImage();
|
||||
int clickImgWidth = image.getWidth();
|
||||
int clickImgHeight = image.getHeight();
|
||||
@@ -78,17 +81,10 @@ public abstract class AbstractClickImageCaptchaGenerator extends AbstractImageCa
|
||||
clickImageCheckDefinition.setHeight(clickImgHeight);
|
||||
clickImageCheckDefinitionList.add(clickImageCheckDefinition);
|
||||
}
|
||||
// 打乱
|
||||
Collections.shuffle(clickImageCheckDefinitionList);
|
||||
// 拿出参与校验的数据
|
||||
List<ClickImageCheckDefinition> checkClickImageCheckDefinitionList = new ArrayList<>(checkClickCount);
|
||||
for (int i = 0; i < checkClickCount; i++) {
|
||||
ClickImageCheckDefinition clickImageCheckDefinition = clickImageCheckDefinitionList.get(i);
|
||||
checkClickImageCheckDefinitionList.add(clickImageCheckDefinition);
|
||||
}
|
||||
// 将校验的文字生成提示图片
|
||||
ImgWrapper tipImage = genTipImage(checkClickImageCheckDefinitionList);
|
||||
return wrapClickImageCaptchaInfo(param, bgImage, tipImage.getImage(), checkClickImageCheckDefinitionList);
|
||||
List<ClickImageCheckDefinition> checkClickImageCheckDefinitionList = getCheckClickImageCheckDefinitionList(clickImageCheckDefinitionList,
|
||||
checkClickCount);
|
||||
// wrap
|
||||
return wrapClickImageCaptchaInfo(param, bgImage, checkClickImageCheckDefinitionList);
|
||||
|
||||
} finally {
|
||||
// 使用完后关闭流
|
||||
@@ -103,31 +99,50 @@ public abstract class AbstractClickImageCaptchaGenerator extends AbstractImageCa
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机获取点击的图片
|
||||
* 从总的图片中 去除要校验的图片数据 以及顺序
|
||||
*
|
||||
* @return ImgWrapper
|
||||
* @param allCheckDefinitionList 总的点选图片
|
||||
* @param checkClickCount 参与校验的数据
|
||||
* @return List<ClickImageCheckDefinition>
|
||||
*/
|
||||
public abstract ImgWrapper randomGetClickImg();
|
||||
protected List<ClickImageCheckDefinition> getCheckClickImageCheckDefinitionList(List<ClickImageCheckDefinition> allCheckDefinitionList,
|
||||
Integer checkClickCount) {
|
||||
// 打乱
|
||||
Collections.shuffle(allCheckDefinitionList);
|
||||
// 拿出参与校验的数据
|
||||
List<ClickImageCheckDefinition> checkClickImageCheckDefinitionList = new ArrayList<>(checkClickCount);
|
||||
for (int i = 0; i < checkClickCount; i++) {
|
||||
ClickImageCheckDefinition clickImageCheckDefinition = allCheckDefinitionList.get(i);
|
||||
checkClickImageCheckDefinitionList.add(clickImageCheckDefinition);
|
||||
}
|
||||
return checkClickImageCheckDefinitionList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 tip 图片
|
||||
* 随机获取一组数据用于生成随机图
|
||||
*
|
||||
* @param imageCheckDefinitions imageCheckDefinitions
|
||||
* @param tipSize tipSize
|
||||
* @return List<String>
|
||||
*/
|
||||
protected abstract List<String> randomGetClickImgTips(int tipSize);
|
||||
|
||||
/**
|
||||
* 随机获取点击的图片
|
||||
*
|
||||
* @param tip 提示数据,根据改数据生成图片
|
||||
* @return ImgWrapper
|
||||
*/
|
||||
public abstract ImgWrapper genTipImage(List<ClickImageCheckDefinition> imageCheckDefinitions);
|
||||
public abstract ImgWrapper getClickImg(String tip);
|
||||
|
||||
/**
|
||||
* 包装 ImageCaptchaInfo
|
||||
*
|
||||
* @param param param
|
||||
* @param bgImage bgImage
|
||||
* @param tipImage tipImage
|
||||
* @param checkClickImageCheckDefinitionList checkClickImageCheckDefinitionList
|
||||
* @return ImageCaptchaInfo
|
||||
*/
|
||||
public abstract ImageCaptchaInfo wrapClickImageCaptchaInfo(GenerateParam param, BufferedImage bgImage,
|
||||
BufferedImage tipImage,
|
||||
List<ClickImageCheckDefinition> checkClickImageCheckDefinitionList);
|
||||
|
||||
/**
|
||||
|
||||
+20
-10
@@ -18,6 +18,7 @@ import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -47,8 +48,8 @@ public class StandardRandomWordClickImageCaptchaGenerator extends AbstractClickI
|
||||
protected int tipImageInterferencePointNum = 5;
|
||||
|
||||
/**
|
||||
* 因为在画文字图形的时候 y 值不能准确通过 除法计算得出, 字体大小不一致中间的容错值不可估计,
|
||||
* 所以通过 线性回归模型 计算出 intercept和coef 用于计算 容错值
|
||||
* 因为在画文字图形的时候 y 值不能准确通过 除法计算得出, 字体大小不一致中间的容错值算不准确
|
||||
* 方案: 通过 线性回归模型 计算出 intercept和coef 用于计算 容错值
|
||||
* 训练数据为 宋体 字体大小为 30~150 随机选择7组数据进行训练, 训练后r2结果为 0.9967106324620846
|
||||
*/
|
||||
protected float intercept = 0.39583333f;
|
||||
@@ -63,6 +64,18 @@ public class StandardRandomWordClickImageCaptchaGenerator extends AbstractClickI
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> randomGetClickImgTips(int tipSize) {
|
||||
ThreadLocalRandom random = ThreadLocalRandom.current();
|
||||
List<String> tipList = new ArrayList<>(tipSize);
|
||||
for (int i = 0; i < tipSize; i++) {
|
||||
String randomWord = FontUtils.getRandomChar(random);
|
||||
tipList.add(randomWord);
|
||||
}
|
||||
// 随机文字
|
||||
return tipList;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows({IOException.class, FontFormatException.class})
|
||||
protected void doInit(boolean initDefaultResource) {
|
||||
@@ -85,14 +98,12 @@ public class StandardRandomWordClickImageCaptchaGenerator extends AbstractClickI
|
||||
this.font = font;
|
||||
}
|
||||
|
||||
|
||||
public void initDefaultResource() {
|
||||
ResourceStore resourceStore = imageCaptchaResourceManager.getResourceStore();
|
||||
// 添加一些系统的资源文件
|
||||
resourceStore.addResource(CaptchaTypeConstant.WORD_IMAGE_CLICK, new Resource(ClassPathResourceProvider.NAME, StandardSliderImageCaptchaGenerator.DEFAULT_SLIDER_IMAGE_RESOURCE_PATH.concat("/1.jpg")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImgWrapper genTipImage(List<ClickImageCheckDefinition> imageCheckDefinitions) {
|
||||
String tips = imageCheckDefinitions.stream().map(ClickImageCheckDefinition::getTip).collect(Collectors.joining());
|
||||
// 生成随机颜色
|
||||
@@ -107,29 +118,28 @@ public class StandardRandomWordClickImageCaptchaGenerator extends AbstractClickI
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImgWrapper randomGetClickImg() {
|
||||
public ImgWrapper getClickImg(String tip) {
|
||||
ThreadLocalRandom random = ThreadLocalRandom.current();
|
||||
// 随机文字
|
||||
String randomWord = FontUtils.getRandomChar(random);
|
||||
// 随机颜色
|
||||
Color randomColor = CaptchaImageUtils.getRandomColor(random);
|
||||
// 随机角度
|
||||
int randomDeg = ThreadLocalRandom.current().nextInt(0, 85);
|
||||
BufferedImage fontImage = CaptchaImageUtils.drawWordImg(randomColor,
|
||||
randomWord,
|
||||
tip,
|
||||
font,
|
||||
currentFontTopCoef,
|
||||
clickImgWidth,
|
||||
clickImgHeight,
|
||||
randomDeg);
|
||||
return new ImgWrapper(fontImage, randomWord);
|
||||
return new ImgWrapper(fontImage, tip);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ImageCaptchaInfo wrapClickImageCaptchaInfo(GenerateParam param, BufferedImage bgImage,
|
||||
BufferedImage tipImage,
|
||||
List<ClickImageCheckDefinition> checkClickImageCheckDefinitionList) {
|
||||
// 提示图片
|
||||
BufferedImage tipImage = genTipImage(checkClickImageCheckDefinitionList).getImage();
|
||||
ImageCaptchaInfo clickImageCaptchaInfo = new ImageCaptchaInfo();
|
||||
clickImageCaptchaInfo.setBackgroundImage(transform(bgImage, param.getBackgroundFormatName()));
|
||||
clickImageCaptchaInfo.setSliderImage(transform(tipImage, param.getSliderFormatName()));
|
||||
|
||||
Reference in New Issue
Block a user