mirror of
https://github.com/dromara/tianai-captcha.git
synced 2026-05-07 06:04:34 +08:00
重构 resource 模块,支持自定义tag标签
重构 transform 模块 修复以及优化各验证码生成器,
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>cloud.tianai.captcha</groupId>
|
||||
<artifactId>tianai-captcha</artifactId>
|
||||
<version>1.3.3</version>
|
||||
<version>1.3.3.1</version>
|
||||
|
||||
<name>tianai-captcha</name>
|
||||
<description>行为验证码</description>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package cloud.tianai.captcha.common.constant;
|
||||
|
||||
public interface CommonConstant {
|
||||
|
||||
String DEFAULT_TAG = "default";
|
||||
/** 图标点选资源存储类型.*/
|
||||
String IMAGE_CLICK_ICON = "ICON";
|
||||
}
|
||||
@@ -4,16 +4,23 @@ import cloud.tianai.captcha.common.exception.ImageCaptchaException;
|
||||
import cloud.tianai.captcha.common.util.CollectionUtils;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.GenerateParam;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.ImageCaptchaInfo;
|
||||
import cloud.tianai.captcha.generator.common.util.CaptchaImageUtils;
|
||||
import cloud.tianai.captcha.generator.impl.transform.Base64ImageTransform;
|
||||
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.ResourceMap;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* @Author: 天爱有情
|
||||
@@ -78,11 +85,11 @@ public abstract class AbstractImageCaptchaGenerator implements ImageCaptchaGener
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public ImageCaptchaInfo generateCaptchaImage(String type, String backgroundFormatName, String sliderFormatName) {
|
||||
public ImageCaptchaInfo generateCaptchaImage(String type, String backgroundFormatName, String templateFormatName) {
|
||||
return generateCaptchaImage(GenerateParam.builder()
|
||||
.type(type)
|
||||
.backgroundFormatName(backgroundFormatName)
|
||||
.sliderFormatName(sliderFormatName)
|
||||
.templateFormatName(templateFormatName)
|
||||
.obfuscate(false)
|
||||
.build());
|
||||
}
|
||||
@@ -94,18 +101,18 @@ public abstract class AbstractImageCaptchaGenerator implements ImageCaptchaGener
|
||||
}
|
||||
|
||||
|
||||
protected Map<String, Resource> requiredRandomGetTemplate(String type) {
|
||||
Map<String, Resource> templateMap = imageCaptchaResourceManager.randomGetTemplate(type);
|
||||
protected ResourceMap requiredRandomGetTemplate(String type, String tag) {
|
||||
ResourceMap templateMap = imageCaptchaResourceManager.randomGetTemplate(type, tag);
|
||||
if (CollectionUtils.isEmpty(templateMap)) {
|
||||
throw new ImageCaptchaException("随机获取模板资源失败, 获取到的资源为空, type=" + type);
|
||||
throw new ImageCaptchaException("随机获取模板资源失败, 获取到的资源为空, type=" + type + ",tag=" + tag);
|
||||
}
|
||||
return templateMap;
|
||||
}
|
||||
|
||||
protected Resource requiredRandomGetResource(String type) {
|
||||
Resource resource = imageCaptchaResourceManager.randomGetResource(type);
|
||||
protected Resource requiredRandomGetResource(String type, String tag) {
|
||||
Resource resource = imageCaptchaResourceManager.randomGetResource(type, tag);
|
||||
if (resource == null) {
|
||||
throw new ImageCaptchaException("随机获取资源失败, 获取到的资源为空, type=" + type);
|
||||
throw new ImageCaptchaException("随机获取资源失败, 获取到的资源为空, type=" + type + ",tag=" + tag);
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
@@ -116,9 +123,71 @@ public abstract class AbstractImageCaptchaGenerator implements ImageCaptchaGener
|
||||
if (resource == null) {
|
||||
throw new IllegalArgumentException("查找模板异常, 该模板下未找到 ".concat(imageName));
|
||||
}
|
||||
return getImageResourceManager().getResourceInputStream(resource);
|
||||
return getResourceInputStream(resource, null);
|
||||
}
|
||||
|
||||
protected BufferedImage getTemplateImage(Map<String, Resource> templateImages, String imageName) {
|
||||
InputStream stream = getTemplateFile(templateImages, imageName);
|
||||
BufferedImage bufferedImage = CaptchaImageUtils.wrapFile2BufferedImage(stream);
|
||||
closeStream(stream);
|
||||
return bufferedImage;
|
||||
}
|
||||
|
||||
|
||||
protected BufferedImage getResourceImage(Resource resource) {
|
||||
InputStream stream = getResourceInputStream(resource, null);
|
||||
BufferedImage bufferedImage = CaptchaImageUtils.wrapFile2BufferedImage(stream);
|
||||
closeStream(stream);
|
||||
return bufferedImage;
|
||||
}
|
||||
|
||||
protected int randomInt(int origin, int bound) {
|
||||
return ThreadLocalRandom.current().nextInt(origin, bound);
|
||||
}
|
||||
protected boolean randomBoolean() {
|
||||
return ThreadLocalRandom.current().nextBoolean();
|
||||
}
|
||||
|
||||
protected int randomInt(int bound) {
|
||||
return ThreadLocalRandom.current().nextInt(bound);
|
||||
}
|
||||
|
||||
public void closeStream(InputStream stream) {
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected InputStream getResourceInputStream(Resource resource, Collection<InputStream> inputStreams) {
|
||||
InputStream stream = getImageResourceManager().getResourceInputStream(resource);
|
||||
if (stream != null && inputStreams != null) {
|
||||
inputStreams.add(stream);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
protected Optional<BufferedImage> getTemplateImageOfOptional(Map<String, Resource> templateImages, String imageName) {
|
||||
Optional<InputStream> optional = getTemplateFileOfOptional(templateImages, imageName);
|
||||
if (optional.isPresent()) {
|
||||
InputStream inputStream = optional.get();
|
||||
BufferedImage bufferedImage = CaptchaImageUtils.wrapFile2BufferedImage(inputStream);
|
||||
closeStream(inputStream);
|
||||
return Optional.ofNullable(bufferedImage);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
protected Optional<InputStream> getTemplateFileOfOptional(Map<String, Resource> templateImages, String imageName) {
|
||||
Resource resource = templateImages.get(imageName);
|
||||
if (resource == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.ofNullable(getResourceInputStream(resource, null));
|
||||
}
|
||||
|
||||
protected void assertInit() {
|
||||
if (!init) {
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package cloud.tianai.captcha.generator;
|
||||
|
||||
import cloud.tianai.captcha.generator.common.model.dto.GenerateParam;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.ImageTransformData;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
/**
|
||||
@@ -12,9 +16,28 @@ public interface ImageTransform {
|
||||
/**
|
||||
* 转换
|
||||
*
|
||||
* @param bufferedImage 图片
|
||||
* @param transformType 转换类型
|
||||
* @param backgroundImage 背景图片
|
||||
* @param param 参数
|
||||
* @param backgroundResource 背景资源对象
|
||||
* @return ImageTransformData
|
||||
*/
|
||||
default ImageTransformData transform(GenerateParam param, BufferedImage backgroundImage, Resource backgroundResource) {
|
||||
return transform(param, backgroundImage, null, backgroundResource, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换
|
||||
*
|
||||
* @param backgroundImage 背景图片
|
||||
* @param templateImage 模板图片(可能为空)
|
||||
* @param param 参数
|
||||
* @param backgroundResource 背景资源对象
|
||||
* @param templateResource 模板资源对象(可能为空)
|
||||
* @return String
|
||||
*/
|
||||
String transform(BufferedImage bufferedImage, String transformType);
|
||||
ImageTransformData transform(GenerateParam param,
|
||||
BufferedImage backgroundImage,
|
||||
BufferedImage templateImage,
|
||||
Object backgroundResource,
|
||||
Object templateResource);
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
package cloud.tianai.captcha.generator.common.model.dto;
|
||||
|
||||
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
@@ -14,7 +15,7 @@ import lombok.NoArgsConstructor;
|
||||
@AllArgsConstructor
|
||||
public class ClickImageCheckDefinition {
|
||||
/** 提示.*/
|
||||
private String tip;
|
||||
private Resource tip;
|
||||
/** x.*/
|
||||
private Integer x;
|
||||
/** y.*/
|
||||
@@ -24,4 +25,4 @@ public class ClickImageCheckDefinition {
|
||||
/** 高.*/
|
||||
private Integer height;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package cloud.tianai.captcha.generator.common.model.dto;
|
||||
|
||||
import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
|
||||
import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
|
||||
import cloud.tianai.captcha.common.constant.CommonConstant;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
@@ -15,12 +15,18 @@ import lombok.*;
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
public class GenerateParam {
|
||||
/** 背景格式化名称.*/
|
||||
/** 背景格式化类型. */
|
||||
private String backgroundFormatName = "jpeg";
|
||||
/** 滑块格式化名称.*/
|
||||
private String sliderFormatName = "png";
|
||||
/** 是否混淆.*/
|
||||
/** 模板图片格式化类型. */
|
||||
private String templateFormatName = "png";
|
||||
/** 是否混淆. */
|
||||
private Boolean obfuscate = false;
|
||||
/** 类型.*/
|
||||
/** 类型. */
|
||||
private String type = CaptchaTypeConstant.SLIDER;
|
||||
/** 背景图片标签, 用户二级过滤背景图片,或指定某背景图片. */
|
||||
private String backgroundImageTag = CommonConstant.DEFAULT_TAG;
|
||||
/** 滑动图片标签,用户二级过滤模板图片,或指定某模板图片.. */
|
||||
private String templateImageTag = CommonConstant.DEFAULT_TAG;
|
||||
/** 扩展参数.*/
|
||||
private Object param;
|
||||
}
|
||||
|
||||
+43
-29
@@ -14,29 +14,29 @@ import lombok.NoArgsConstructor;
|
||||
@NoArgsConstructor
|
||||
public class ImageCaptchaInfo {
|
||||
|
||||
/**
|
||||
* 背景图
|
||||
*/
|
||||
/** 背景图. */
|
||||
private String backgroundImage;
|
||||
/**
|
||||
* 移动图
|
||||
*/
|
||||
private String sliderImage;
|
||||
/** 模板图. */
|
||||
private String templateImage;
|
||||
/** 背景图片所属标签. */
|
||||
private String backgroundImageTag;
|
||||
/** 模板图片所属标签. */
|
||||
private String templateImageTag;
|
||||
/** 背景图片宽度. */
|
||||
private Integer bgImageWidth;
|
||||
private Integer backgroundImageWidth;
|
||||
/** 背景图片高度. */
|
||||
private Integer bgImageHeight;
|
||||
private Integer backgroundImageHeight;
|
||||
/** 滑块图片宽度. */
|
||||
private Integer sliderImageWidth;
|
||||
private Integer templateImageWidth;
|
||||
/** 滑块图片高度. */
|
||||
private Integer sliderImageHeight;
|
||||
private Integer templateImageHeight;
|
||||
/** 随机值. */
|
||||
private Integer randomX;
|
||||
/** 容错值, 可以为空 默认 0.02容错,校验的时候用. */
|
||||
private Float tolerant;
|
||||
/** 验证码类型. */
|
||||
private String type;
|
||||
/** 透传字段,用于传给前端.*/
|
||||
/** 透传字段,用于传给前端. */
|
||||
private Object data;
|
||||
/**
|
||||
* 扩展字段
|
||||
@@ -44,32 +44,46 @@ public class ImageCaptchaInfo {
|
||||
public Object expand;
|
||||
|
||||
public ImageCaptchaInfo(String backgroundImage,
|
||||
String sliderImage,
|
||||
Integer bgImageWidth,
|
||||
Integer bgImageHeight,
|
||||
Integer sliderImageWidth,
|
||||
Integer sliderImageHeight,
|
||||
String templateImage,
|
||||
String backgroundImageTag,
|
||||
String templateImageTag,
|
||||
Integer backgroundImageWidth,
|
||||
Integer backgroundImageHeight,
|
||||
Integer templateImageWidth,
|
||||
Integer templateImageHeight,
|
||||
Integer randomX,
|
||||
String type) {
|
||||
this.backgroundImage = backgroundImage;
|
||||
this.sliderImage = sliderImage;
|
||||
this.bgImageWidth = bgImageWidth;
|
||||
this.bgImageHeight = bgImageHeight;
|
||||
this.sliderImageWidth = sliderImageWidth;
|
||||
this.sliderImageHeight = sliderImageHeight;
|
||||
this.templateImage = templateImage;
|
||||
this.backgroundImageTag = backgroundImageTag;
|
||||
this.templateImageTag = templateImageTag;
|
||||
this.backgroundImageWidth = backgroundImageWidth;
|
||||
this.backgroundImageHeight = backgroundImageHeight;
|
||||
this.templateImageWidth = templateImageWidth;
|
||||
this.templateImageHeight = templateImageHeight;
|
||||
this.randomX = randomX;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static ImageCaptchaInfo of(String backgroundImage,
|
||||
String sliderImage,
|
||||
Integer bgImageWidth,
|
||||
Integer bgImageHeight,
|
||||
Integer sliderImageWidth,
|
||||
Integer sliderImageHeight,
|
||||
Integer randomKey,
|
||||
String templateImage,
|
||||
String backgroundImageTag,
|
||||
String templateImageTag,
|
||||
Integer backgroundImageWidth,
|
||||
Integer backgroundImageHeight,
|
||||
Integer templateImageWidth,
|
||||
Integer templateImageHeight,
|
||||
Integer randomX,
|
||||
String type) {
|
||||
return new ImageCaptchaInfo(backgroundImage, sliderImage, bgImageWidth, bgImageHeight, sliderImageWidth, sliderImageHeight, randomKey, type);
|
||||
return new ImageCaptchaInfo(backgroundImage,
|
||||
templateImage,
|
||||
backgroundImageTag,
|
||||
templateImageTag,
|
||||
backgroundImageWidth,
|
||||
backgroundImageHeight,
|
||||
templateImageWidth,
|
||||
templateImageHeight,
|
||||
randomX, type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package cloud.tianai.captcha.generator.common.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @Author: 天爱有情
|
||||
* @date 2023/1/5 11:39
|
||||
* @Description 图片转换成url后的对象
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class ImageTransformData {
|
||||
/** 背景图. */
|
||||
private String backgroundImageUrl;
|
||||
/** 模板图. */
|
||||
private String templateImageUrl;
|
||||
/** 留一个扩展数据. */
|
||||
private Object data;
|
||||
|
||||
public ImageTransformData(String backgroundImageUrl, String templateImageUrl) {
|
||||
this.backgroundImageUrl = backgroundImageUrl;
|
||||
this.templateImageUrl = templateImageUrl;
|
||||
}
|
||||
}
|
||||
+12
-9
@@ -1,6 +1,5 @@
|
||||
package cloud.tianai.captcha.generator.common.model.dto;
|
||||
|
||||
import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
|
||||
import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -25,21 +24,25 @@ public class RotateImageCaptchaInfo extends ImageCaptchaInfo {
|
||||
public static RotateImageCaptchaInfo of(Double degree,
|
||||
Integer randomX,
|
||||
String backgroundImage,
|
||||
String sliderImage,
|
||||
String templateImage,
|
||||
String backgroundImageTag,
|
||||
String templateImageTag,
|
||||
Integer bgImageWidth,
|
||||
Integer bgImageHeight,
|
||||
Integer sliderImageWidth,
|
||||
Integer sliderImageHeight) {
|
||||
Integer templateImageWidth,
|
||||
Integer templateImageHeight) {
|
||||
RotateImageCaptchaInfo rotateImageCaptchaInfo = new RotateImageCaptchaInfo();
|
||||
rotateImageCaptchaInfo.setDegree(degree);
|
||||
rotateImageCaptchaInfo.setRandomX(randomX);
|
||||
rotateImageCaptchaInfo.setBackgroundImage(backgroundImage);
|
||||
rotateImageCaptchaInfo.setBackgroundImageTag(backgroundImageTag);
|
||||
rotateImageCaptchaInfo.setTemplateImage(templateImageTag);
|
||||
rotateImageCaptchaInfo.setTolerant(DEFAULT_TOLERANT);
|
||||
rotateImageCaptchaInfo.setSliderImage(sliderImage);
|
||||
rotateImageCaptchaInfo.setBgImageWidth(bgImageWidth);
|
||||
rotateImageCaptchaInfo.setBgImageHeight(bgImageHeight);
|
||||
rotateImageCaptchaInfo.setSliderImageWidth(sliderImageWidth);
|
||||
rotateImageCaptchaInfo.setSliderImageHeight(sliderImageHeight);
|
||||
rotateImageCaptchaInfo.setTemplateImage(templateImage);
|
||||
rotateImageCaptchaInfo.setBackgroundImageWidth(bgImageWidth);
|
||||
rotateImageCaptchaInfo.setBackgroundImageHeight(bgImageHeight);
|
||||
rotateImageCaptchaInfo.setTemplateImageWidth(templateImageWidth);
|
||||
rotateImageCaptchaInfo.setTemplateImageHeight(templateImageHeight);
|
||||
// 类型为旋转图片验证码
|
||||
rotateImageCaptchaInfo.setType(CaptchaTypeConstant.ROTATE);
|
||||
return rotateImageCaptchaInfo;
|
||||
|
||||
+10
-7
@@ -1,6 +1,5 @@
|
||||
package cloud.tianai.captcha.generator.common.model.dto;
|
||||
|
||||
import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
|
||||
import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -23,7 +22,9 @@ public class SliderImageCaptchaInfo extends ImageCaptchaInfo {
|
||||
public static SliderImageCaptchaInfo of(Integer x,
|
||||
Integer y,
|
||||
String backgroundImage,
|
||||
String sliderImage,
|
||||
String templateImage,
|
||||
String backgroundImageTag,
|
||||
String templateImageTag,
|
||||
Integer bgImageWidth,
|
||||
Integer bgImageHeight,
|
||||
Integer sliderImageWidth,
|
||||
@@ -33,11 +34,13 @@ public class SliderImageCaptchaInfo extends ImageCaptchaInfo {
|
||||
sliderImageCaptchaInfo.setY(y);
|
||||
sliderImageCaptchaInfo.setRandomX(x);
|
||||
sliderImageCaptchaInfo.setBackgroundImage(backgroundImage);
|
||||
sliderImageCaptchaInfo.setSliderImage(sliderImage);
|
||||
sliderImageCaptchaInfo.setBgImageWidth(bgImageWidth);
|
||||
sliderImageCaptchaInfo.setBgImageHeight(bgImageHeight);
|
||||
sliderImageCaptchaInfo.setSliderImageWidth(sliderImageWidth);
|
||||
sliderImageCaptchaInfo.setSliderImageHeight(sliderImageHeight);
|
||||
sliderImageCaptchaInfo.setTemplateImage(templateImage);
|
||||
sliderImageCaptchaInfo.setBackgroundImageTag(backgroundImageTag);
|
||||
sliderImageCaptchaInfo.setTemplateImageTag(templateImageTag);
|
||||
sliderImageCaptchaInfo.setBackgroundImageWidth(bgImageWidth);
|
||||
sliderImageCaptchaInfo.setBackgroundImageHeight(bgImageHeight);
|
||||
sliderImageCaptchaInfo.setTemplateImageWidth(sliderImageWidth);
|
||||
sliderImageCaptchaInfo.setTemplateImageHeight(sliderImageHeight);
|
||||
sliderImageCaptchaInfo.setType(CaptchaTypeConstant.SLIDER);
|
||||
return sliderImageCaptchaInfo;
|
||||
}
|
||||
|
||||
+50
-82
@@ -7,12 +7,14 @@ import cloud.tianai.captcha.generator.common.model.dto.ImageCaptchaInfo;
|
||||
import cloud.tianai.captcha.generator.common.util.CaptchaImageUtils;
|
||||
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
||||
import lombok.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
@@ -22,14 +24,6 @@ import java.util.concurrent.ThreadLocalRandom;
|
||||
*/
|
||||
public abstract class AbstractClickImageCaptchaGenerator extends AbstractImageCaptchaGenerator {
|
||||
|
||||
/** 参与校验的数量. */
|
||||
@Getter
|
||||
@Setter
|
||||
protected Integer checkClickCount = 4;
|
||||
/** 干扰数量. */
|
||||
@Getter
|
||||
@Setter
|
||||
protected Integer interferenceCount = 2;
|
||||
|
||||
public AbstractClickImageCaptchaGenerator(ImageCaptchaResourceManager imageCaptchaResourceManager) {
|
||||
super(imageCaptchaResourceManager);
|
||||
@@ -42,89 +36,62 @@ public abstract class AbstractClickImageCaptchaGenerator extends AbstractImageCa
|
||||
@Override
|
||||
public ImageCaptchaInfo doGenerateCaptchaImage(GenerateParam param) {
|
||||
// 文字点选验证码不需要模板 只需要背景图
|
||||
Collection<InputStream> inputStreams = new LinkedList<>();
|
||||
try {
|
||||
Resource resourceImage = requiredRandomGetResource(param.getType());
|
||||
InputStream resourceInputStream = getImageResourceManager().getResourceInputStream(resourceImage);
|
||||
inputStreams.add(resourceInputStream);
|
||||
BufferedImage bgImage = CaptchaImageUtils.wrapFile2BufferedImage(resourceInputStream);
|
||||
Resource resourceImage = requiredRandomGetResource(param.getType(), param.getBackgroundImageTag());
|
||||
|
||||
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 = getClickImg(imgTips.get(i));
|
||||
BufferedImage image = imgWrapper.getImage();
|
||||
int clickImgWidth = image.getWidth();
|
||||
int clickImgHeight = image.getHeight();
|
||||
// 随机x
|
||||
int randomX;
|
||||
if (i == 0) {
|
||||
randomX = 1;
|
||||
} else {
|
||||
randomX = avg * i;
|
||||
}
|
||||
// 随机y
|
||||
int randomY = ThreadLocalRandom.current().nextInt(10, bgImage.getHeight() - clickImgHeight);
|
||||
// 通过随机x和y 进行覆盖图片
|
||||
CaptchaImageUtils.overlayImage(bgImage, imgWrapper.getImage(), randomX, randomY);
|
||||
ClickImageCheckDefinition clickImageCheckDefinition = new ClickImageCheckDefinition();
|
||||
clickImageCheckDefinition.setTip(imgWrapper.getTip());
|
||||
clickImageCheckDefinition.setX(randomX + clickImgWidth / 2);
|
||||
clickImageCheckDefinition.setY(randomY + clickImgHeight / 2);
|
||||
clickImageCheckDefinition.setWidth(clickImgWidth);
|
||||
clickImageCheckDefinition.setHeight(clickImgHeight);
|
||||
clickImageCheckDefinitionList.add(clickImageCheckDefinition);
|
||||
}
|
||||
List<ClickImageCheckDefinition> checkClickImageCheckDefinitionList = getCheckClickImageCheckDefinitionList(clickImageCheckDefinitionList,
|
||||
checkClickCount);
|
||||
// wrap
|
||||
return wrapClickImageCaptchaInfo(param, bgImage, checkClickImageCheckDefinitionList);
|
||||
BufferedImage bgImage = getResourceImage(resourceImage);
|
||||
|
||||
} finally {
|
||||
// 使用完后关闭流
|
||||
for (InputStream inputStream : inputStreams) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
List<Resource> imgTips = randomGetClickImgTips(param);
|
||||
int allImages = imgTips.size();
|
||||
List<ClickImageCheckDefinition> clickImageCheckDefinitionList = new ArrayList<>(allImages);
|
||||
int avg = bgImage.getWidth() / allImages;
|
||||
if (allImages < imgTips.size()) {
|
||||
throw new IllegalStateException("随机生成点击图片小于请求数量, 请求生成数量=" + allImages + ",实际生成数量=" + imgTips.size());
|
||||
}
|
||||
for (int i = 0; i < allImages; i++) {
|
||||
// 随机获取点击图片
|
||||
ImgWrapper imgWrapper = getClickImg(imgTips.get(i));
|
||||
BufferedImage image = imgWrapper.getImage();
|
||||
int clickImgWidth = image.getWidth();
|
||||
int clickImgHeight = image.getHeight();
|
||||
// 随机x
|
||||
int randomX;
|
||||
if (i == 0) {
|
||||
randomX = 1;
|
||||
} else {
|
||||
randomX = avg * i;
|
||||
}
|
||||
// 随机y
|
||||
int randomY = randomInt(10, bgImage.getHeight() - clickImgHeight);
|
||||
// 通过随机x和y 进行覆盖图片
|
||||
CaptchaImageUtils.overlayImage(bgImage, imgWrapper.getImage(), randomX, randomY);
|
||||
ClickImageCheckDefinition clickImageCheckDefinition = new ClickImageCheckDefinition();
|
||||
clickImageCheckDefinition.setTip(imgWrapper.getTip());
|
||||
clickImageCheckDefinition.setX(randomX + clickImgWidth / 2);
|
||||
clickImageCheckDefinition.setY(randomY + clickImgHeight / 2);
|
||||
clickImageCheckDefinition.setWidth(clickImgWidth);
|
||||
clickImageCheckDefinition.setHeight(clickImgHeight);
|
||||
clickImageCheckDefinitionList.add(clickImageCheckDefinition);
|
||||
}
|
||||
List<ClickImageCheckDefinition> checkClickImageCheckDefinitionList = filterAndSortClickImageCheckDefinition(clickImageCheckDefinitionList);
|
||||
// wrap
|
||||
return wrapClickImageCaptchaInfo(param, bgImage, checkClickImageCheckDefinitionList, resourceImage);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 从总的图片中 去除要校验的图片数据 以及顺序
|
||||
* 过滤并排序校验的图片点选顺序
|
||||
*
|
||||
* @param allCheckDefinitionList 总的点选图片
|
||||
* @param checkClickCount 参与校验的数据
|
||||
* @return List<ClickImageCheckDefinition>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
protected abstract List<ClickImageCheckDefinition> filterAndSortClickImageCheckDefinition(List<ClickImageCheckDefinition> allCheckDefinitionList);
|
||||
|
||||
/**
|
||||
* 随机获取一组数据用于生成随机图
|
||||
*
|
||||
* @param tipSize tipSize
|
||||
* @return List<String>
|
||||
*/
|
||||
protected abstract List<String> randomGetClickImgTips(int tipSize);
|
||||
protected abstract List<Resource> randomGetClickImgTips(GenerateParam param);
|
||||
|
||||
/**
|
||||
* 随机获取点击的图片
|
||||
@@ -132,7 +99,7 @@ public abstract class AbstractClickImageCaptchaGenerator extends AbstractImageCa
|
||||
* @param tip 提示数据,根据改数据生成图片
|
||||
* @return ImgWrapper
|
||||
*/
|
||||
public abstract ImgWrapper getClickImg(String tip);
|
||||
public abstract ImgWrapper getClickImg(Resource tip);
|
||||
|
||||
/**
|
||||
* 包装 ImageCaptchaInfo
|
||||
@@ -140,10 +107,11 @@ public abstract class AbstractClickImageCaptchaGenerator extends AbstractImageCa
|
||||
* @param param param
|
||||
* @param bgImage bgImage
|
||||
* @param checkClickImageCheckDefinitionList checkClickImageCheckDefinitionList
|
||||
* @param resourceImage 随机读取到的图片资源
|
||||
* @return ImageCaptchaInfo
|
||||
*/
|
||||
public abstract ImageCaptchaInfo wrapClickImageCaptchaInfo(GenerateParam param, BufferedImage bgImage,
|
||||
List<ClickImageCheckDefinition> checkClickImageCheckDefinitionList);
|
||||
List<ClickImageCheckDefinition> checkClickImageCheckDefinitionList, Resource resourceImage);
|
||||
|
||||
/**
|
||||
* @Author: 天爱有情
|
||||
@@ -157,6 +125,6 @@ public abstract class AbstractClickImageCaptchaGenerator extends AbstractImageCa
|
||||
/** 图片. */
|
||||
private BufferedImage image;
|
||||
/** 提示. */
|
||||
private String tip;
|
||||
private Resource tip;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ public class CacheImageCaptchaGenerator implements ImageCaptchaGenerator {
|
||||
|
||||
@Override
|
||||
public ImageCaptchaInfo generateCaptchaImage(String type, String targetFormatName, String matrixFormatName) {
|
||||
return generateCaptchaImage(GenerateParam.builder().type(type).backgroundFormatName(targetFormatName).sliderFormatName(matrixFormatName).build(), true);
|
||||
return generateCaptchaImage(GenerateParam.builder().type(type).backgroundFormatName(targetFormatName).templateFormatName(matrixFormatName).build(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+10
-5
@@ -5,6 +5,7 @@ import cloud.tianai.captcha.generator.AbstractImageCaptchaGenerator;
|
||||
import cloud.tianai.captcha.generator.ImageTransform;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.GenerateParam;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.ImageCaptchaInfo;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.ImageTransformData;
|
||||
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
|
||||
import cloud.tianai.captcha.resource.ResourceStore;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
||||
@@ -55,7 +56,7 @@ public class StandardConcatImageCaptchaGenerator extends AbstractImageCaptchaGen
|
||||
// 拼接验证码不需要模板 只需要背景图
|
||||
Collection<InputStream> inputStreams = new LinkedList<>();
|
||||
try {
|
||||
Resource resourceImage = requiredRandomGetResource(param.getType());
|
||||
Resource resourceImage = requiredRandomGetResource(param.getType(), param.getBackgroundImageTag());
|
||||
InputStream resourceInputStream = imageCaptchaResourceManager.getResourceInputStream(resourceImage);
|
||||
inputStreams.add(resourceInputStream);
|
||||
BufferedImage bgImage = wrapFile2BufferedImage(resourceInputStream);
|
||||
@@ -71,7 +72,7 @@ public class StandardConcatImageCaptchaGenerator extends AbstractImageCaptchaGen
|
||||
+ bgImageTopSplit[1].getWidth(), bgImageTopSplit[0].getHeight(), bgImageTopSplit[1], bgImageTopSplit[0]);
|
||||
bgImage = concatImage(false, bgImageSplit[1].getWidth(), sliderImage.getHeight() + bgImageSplit[1].getHeight(),
|
||||
sliderImage, bgImageSplit[1]);
|
||||
return wrapConcatCaptchaInfo(randomX, randomY, bgImage, param);
|
||||
return wrapConcatCaptchaInfo(randomX, randomY, bgImage, param, resourceImage);
|
||||
} finally {
|
||||
// 使用完后关闭流
|
||||
for (InputStream inputStream : inputStreams) {
|
||||
@@ -85,9 +86,13 @@ public class StandardConcatImageCaptchaGenerator extends AbstractImageCaptchaGen
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private ImageCaptchaInfo wrapConcatCaptchaInfo(int randomX, int randomY, BufferedImage bgImage, GenerateParam param) {
|
||||
String backGroundImageBase64 = getImageTransform().transform(bgImage, param.getBackgroundFormatName());
|
||||
ImageCaptchaInfo imageCaptchaInfo = ImageCaptchaInfo.of(backGroundImageBase64,
|
||||
private ImageCaptchaInfo wrapConcatCaptchaInfo(int randomX, int randomY, BufferedImage bgImage, GenerateParam param, Resource resourceImage) {
|
||||
|
||||
ImageTransformData transform = getImageTransform().transform(param, bgImage, resourceImage);
|
||||
|
||||
ImageCaptchaInfo imageCaptchaInfo = ImageCaptchaInfo.of(transform.getBackgroundImageUrl(),
|
||||
null,
|
||||
resourceImage.getTag(),
|
||||
null,
|
||||
bgImage.getWidth(),
|
||||
bgImage.getHeight(),
|
||||
|
||||
+40
-16
@@ -6,6 +6,7 @@ import cloud.tianai.captcha.generator.ImageTransform;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.ClickImageCheckDefinition;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.GenerateParam;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.ImageCaptchaInfo;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.ImageTransformData;
|
||||
import cloud.tianai.captcha.generator.common.util.CaptchaImageUtils;
|
||||
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
|
||||
import cloud.tianai.captcha.resource.ResourceStore;
|
||||
@@ -20,6 +21,7 @@ import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -47,6 +49,14 @@ public class StandardRandomWordClickImageCaptchaGenerator extends AbstractClickI
|
||||
@Getter
|
||||
@Setter
|
||||
protected int tipImageInterferencePointNum = 5;
|
||||
/** 参与校验的数量. */
|
||||
@Getter
|
||||
@Setter
|
||||
protected Integer checkClickCount = 4;
|
||||
/** 干扰数量. */
|
||||
@Getter
|
||||
@Setter
|
||||
protected Integer interferenceCount = 2;
|
||||
|
||||
/**
|
||||
* 因为在画文字图形的时候 y 值不能准确通过 除法计算得出, 字体大小不一致中间的容错值算不准确
|
||||
@@ -66,14 +76,14 @@ public class StandardRandomWordClickImageCaptchaGenerator extends AbstractClickI
|
||||
super(imageCaptchaResourceManager);
|
||||
setImageTransform(imageTransform);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> randomGetClickImgTips(int tipSize) {
|
||||
protected List<Resource> randomGetClickImgTips(GenerateParam param) {
|
||||
int tipSize = interferenceCount + checkClickCount;
|
||||
ThreadLocalRandom random = ThreadLocalRandom.current();
|
||||
List<String> tipList = new ArrayList<>(tipSize);
|
||||
List<Resource> tipList = new ArrayList<>(tipSize);
|
||||
for (int i = 0; i < tipSize; i++) {
|
||||
String randomWord = FontUtils.getRandomChar(random);
|
||||
tipList.add(randomWord);
|
||||
tipList.add(new Resource(null, randomWord));
|
||||
}
|
||||
// 随机文字
|
||||
return tipList;
|
||||
@@ -108,7 +118,7 @@ public class StandardRandomWordClickImageCaptchaGenerator extends AbstractClickI
|
||||
}
|
||||
|
||||
public ImgWrapper genTipImage(List<ClickImageCheckDefinition> imageCheckDefinitions) {
|
||||
String tips = imageCheckDefinitions.stream().map(ClickImageCheckDefinition::getTip).collect(Collectors.joining());
|
||||
String tips = imageCheckDefinitions.stream().map(c -> c.getTip().getData()).collect(Collectors.joining());
|
||||
// 生成随机颜色
|
||||
int fontWidth = tips.length() * font.getSize();
|
||||
int width = fontWidth + 6;
|
||||
@@ -117,18 +127,18 @@ public class StandardRandomWordClickImageCaptchaGenerator extends AbstractClickI
|
||||
float top = 6 / 2f + font.getSize() - currentFontTopCoef;
|
||||
BufferedImage bufferedImage = CaptchaImageUtils.genSimpleImgCaptcha(tips,
|
||||
font, width, height, left, top, tipImageInterferenceLineNum, tipImageInterferencePointNum);
|
||||
return new ImgWrapper(bufferedImage, tips);
|
||||
return new ImgWrapper(bufferedImage, new Resource(null, tips));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImgWrapper getClickImg(String tip) {
|
||||
public ImgWrapper getClickImg(Resource tip) {
|
||||
ThreadLocalRandom random = ThreadLocalRandom.current();
|
||||
// 随机颜色
|
||||
Color randomColor = CaptchaImageUtils.getRandomColor(random);
|
||||
// 随机角度
|
||||
int randomDeg = ThreadLocalRandom.current().nextInt(0, 85);
|
||||
int randomDeg = randomInt(0, 85);
|
||||
BufferedImage fontImage = CaptchaImageUtils.drawWordImg(randomColor,
|
||||
tip,
|
||||
tip.getData(),
|
||||
font,
|
||||
currentFontTopCoef,
|
||||
clickImgWidth,
|
||||
@@ -137,19 +147,33 @@ public class StandardRandomWordClickImageCaptchaGenerator extends AbstractClickI
|
||||
return new ImgWrapper(fontImage, tip);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ClickImageCheckDefinition> filterAndSortClickImageCheckDefinition(List<ClickImageCheckDefinition> allCheckDefinitionList) {
|
||||
// 打乱
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageCaptchaInfo wrapClickImageCaptchaInfo(GenerateParam param, BufferedImage bgImage,
|
||||
List<ClickImageCheckDefinition> checkClickImageCheckDefinitionList) {
|
||||
List<ClickImageCheckDefinition> checkClickImageCheckDefinitionList, Resource resourceImage) {
|
||||
// 提示图片
|
||||
BufferedImage tipImage = genTipImage(checkClickImageCheckDefinitionList).getImage();
|
||||
ImageTransformData transform = getImageTransform().transform(param, bgImage, tipImage, resourceImage, checkClickImageCheckDefinitionList);
|
||||
ImageCaptchaInfo clickImageCaptchaInfo = new ImageCaptchaInfo();
|
||||
clickImageCaptchaInfo.setBackgroundImage(getImageTransform().transform(bgImage, param.getBackgroundFormatName()));
|
||||
clickImageCaptchaInfo.setSliderImage(getImageTransform().transform(tipImage, param.getSliderFormatName()));
|
||||
clickImageCaptchaInfo.setBgImageWidth(bgImage.getWidth());
|
||||
clickImageCaptchaInfo.setBgImageHeight(bgImage.getHeight());
|
||||
clickImageCaptchaInfo.setSliderImageWidth(tipImage.getWidth());
|
||||
clickImageCaptchaInfo.setSliderImageHeight(tipImage.getHeight());
|
||||
clickImageCaptchaInfo.setBackgroundImage(transform.getBackgroundImageUrl());
|
||||
clickImageCaptchaInfo.setBackgroundImageTag(resourceImage.getTag());
|
||||
clickImageCaptchaInfo.setTemplateImage(transform.getTemplateImageUrl());
|
||||
clickImageCaptchaInfo.setBackgroundImageWidth(bgImage.getWidth());
|
||||
clickImageCaptchaInfo.setBackgroundImageHeight(bgImage.getHeight());
|
||||
clickImageCaptchaInfo.setTemplateImageWidth(tipImage.getWidth());
|
||||
clickImageCaptchaInfo.setTemplateImageHeight(tipImage.getHeight());
|
||||
clickImageCaptchaInfo.setRandomX(null);
|
||||
clickImageCaptchaInfo.setTolerant(null);
|
||||
clickImageCaptchaInfo.setType(CaptchaTypeConstant.WORD_IMAGE_CLICK);
|
||||
|
||||
+14
-11
@@ -6,11 +6,13 @@ import cloud.tianai.captcha.generator.ImageTransform;
|
||||
import cloud.tianai.captcha.generator.common.constant.SliderCaptchaConstant;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.GenerateParam;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.ImageCaptchaInfo;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.ImageTransformData;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.RotateImageCaptchaInfo;
|
||||
import cloud.tianai.captcha.generator.common.util.CaptchaImageUtils;
|
||||
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
|
||||
import cloud.tianai.captcha.resource.ResourceStore;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.ResourceMap;
|
||||
import cloud.tianai.captcha.resource.impl.provider.ClassPathResourceProvider;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
@@ -23,6 +25,8 @@ import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import static cloud.tianai.captcha.common.constant.CommonConstant.DEFAULT_TAG;
|
||||
|
||||
/**
|
||||
* @Author: 天爱有情
|
||||
* @date 2022/4/22 16:43
|
||||
@@ -52,7 +56,7 @@ public class StandardRotateImageCaptchaGenerator extends AbstractImageCaptchaGen
|
||||
resourceStore.addResource(CaptchaTypeConstant.ROTATE, new Resource(ClassPathResourceProvider.NAME, StandardSliderImageCaptchaGenerator.DEFAULT_SLIDER_IMAGE_RESOURCE_PATH.concat("/1.jpg")));
|
||||
|
||||
// 添加一些系统的 模板文件
|
||||
Map<String, Resource> template1 = new HashMap<>(4);
|
||||
ResourceMap template1 = new ResourceMap(DEFAULT_TAG, 4);
|
||||
template1.put(SliderCaptchaConstant.TEMPLATE_ACTIVE_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, StandardSliderImageCaptchaGenerator.DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/3/active.png")));
|
||||
template1.put(SliderCaptchaConstant.TEMPLATE_FIXED_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, StandardSliderImageCaptchaGenerator.DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/3/fixed.png")));
|
||||
template1.put(SliderCaptchaConstant.TEMPLATE_MATRIX_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, StandardSliderImageCaptchaGenerator.DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/3/matrix.png")));
|
||||
@@ -62,10 +66,10 @@ public class StandardRotateImageCaptchaGenerator extends AbstractImageCaptchaGen
|
||||
@Override
|
||||
public ImageCaptchaInfo doGenerateCaptchaImage(GenerateParam param) {
|
||||
// 旋转验证码没有混淆
|
||||
Map<String, Resource> templateImages = requiredRandomGetTemplate(param.getType());
|
||||
ResourceMap templateImages = requiredRandomGetTemplate(param.getType(), param.getTemplateImageTag());
|
||||
Collection<InputStream> inputStreams = new LinkedList<>();
|
||||
try {
|
||||
Resource resourceImage = requiredRandomGetResource(param.getType());
|
||||
Resource resourceImage = requiredRandomGetResource(param.getType(), param.getBackgroundImageTag());
|
||||
InputStream resourceInputStream = imageCaptchaResourceManager.getResourceInputStream(resourceImage);
|
||||
inputStreams.add(resourceInputStream);
|
||||
BufferedImage cutBackground = CaptchaImageUtils.wrapFile2BufferedImage(resourceInputStream);
|
||||
@@ -96,7 +100,7 @@ public class StandardRotateImageCaptchaGenerator extends AbstractImageCaptchaGen
|
||||
int randomX = ThreadLocalRandom.current().nextInt(fixedTemplate.getWidth() + 10, targetBackground.getWidth() - 10);
|
||||
double degree = 360d - randomX / ((targetBackground.getWidth()) / 360d);
|
||||
CaptchaImageUtils.centerOverlayAndRotateImage(matrixTemplate, cutImage, degree);
|
||||
return wrapRotateCaptchaInfo(degree, randomX, targetBackground, matrixTemplate, param);
|
||||
return wrapRotateCaptchaInfo(degree, randomX, targetBackground, matrixTemplate, param, templateImages, resourceImage);
|
||||
} finally {
|
||||
// 使用完后关闭流
|
||||
for (InputStream inputStream : inputStreams) {
|
||||
@@ -110,15 +114,14 @@ public class StandardRotateImageCaptchaGenerator extends AbstractImageCaptchaGen
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private ImageCaptchaInfo wrapRotateCaptchaInfo(double degree, int randomX, BufferedImage backgroundImage, BufferedImage sliderImage, GenerateParam param) {
|
||||
String backgroundFormatName = param.getBackgroundFormatName();
|
||||
String sliderFormatName = param.getSliderFormatName();
|
||||
String backGroundImageBase64 = getImageTransform().transform(backgroundImage, backgroundFormatName);
|
||||
String sliderImageBase64 = getImageTransform().transform(sliderImage, sliderFormatName);
|
||||
private ImageCaptchaInfo wrapRotateCaptchaInfo(double degree, int randomX, BufferedImage backgroundImage, BufferedImage sliderImage, GenerateParam param, ResourceMap templateResource, Resource resourceImage) {
|
||||
ImageTransformData transform = getImageTransform().transform(param, backgroundImage, sliderImage, resourceImage, templateResource);
|
||||
return RotateImageCaptchaInfo.of(degree,
|
||||
randomX,
|
||||
backGroundImageBase64,
|
||||
sliderImageBase64,
|
||||
transform.getBackgroundImageUrl(),
|
||||
transform.getTemplateImageUrl(),
|
||||
resourceImage.getTag(),
|
||||
templateResource.getTag(),
|
||||
backgroundImage.getWidth(), backgroundImage.getHeight(),
|
||||
sliderImage.getWidth(), sliderImage.getHeight()
|
||||
);
|
||||
|
||||
+18
-12
@@ -6,11 +6,13 @@ import cloud.tianai.captcha.generator.ImageTransform;
|
||||
import cloud.tianai.captcha.generator.common.constant.SliderCaptchaConstant;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.GenerateParam;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.ImageCaptchaInfo;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.ImageTransformData;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.SliderImageCaptchaInfo;
|
||||
import cloud.tianai.captcha.generator.common.util.CaptchaImageUtils;
|
||||
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
|
||||
import cloud.tianai.captcha.resource.ResourceStore;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.ResourceMap;
|
||||
import cloud.tianai.captcha.resource.impl.provider.ClassPathResourceProvider;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -24,6 +26,8 @@ import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import static cloud.tianai.captcha.common.constant.CommonConstant.DEFAULT_TAG;
|
||||
|
||||
/**
|
||||
* @Author: 天爱有情
|
||||
* @Date 2020/5/29 8:06
|
||||
@@ -61,10 +65,10 @@ public class StandardSliderImageCaptchaGenerator extends AbstractImageCaptchaGen
|
||||
@Override
|
||||
public ImageCaptchaInfo doGenerateCaptchaImage(GenerateParam param) {
|
||||
Boolean obfuscate = param.getObfuscate();
|
||||
Map<String, Resource> templateImages = requiredRandomGetTemplate(param.getType());
|
||||
ResourceMap templateImages = requiredRandomGetTemplate(param.getType(), param.getTemplateImageTag());
|
||||
Collection<InputStream> inputStreams = new LinkedList<>();
|
||||
try {
|
||||
Resource resourceImage = requiredRandomGetResource(param.getType());
|
||||
Resource resourceImage = requiredRandomGetResource(param.getType(), param.getBackgroundImageTag());
|
||||
InputStream resourceInputStream = imageCaptchaResourceManager.getResourceInputStream(resourceImage);
|
||||
inputStreams.add(resourceInputStream);
|
||||
BufferedImage cutBackground = CaptchaImageUtils.wrapFile2BufferedImage(resourceInputStream);
|
||||
@@ -99,7 +103,7 @@ public class StandardSliderImageCaptchaGenerator extends AbstractImageCaptchaGen
|
||||
BufferedImage cutImage = CaptchaImageUtils.cutImage(cutBackground, fixedTemplate, randomX, randomY);
|
||||
CaptchaImageUtils.overlayImage(cutImage, activeTemplate, 0, 0);
|
||||
CaptchaImageUtils.overlayImage(matrixTemplate, cutImage, 0, randomY);
|
||||
return wrapSliderCaptchaInfo(randomX, randomY, targetBackground, matrixTemplate, param);
|
||||
return wrapSliderCaptchaInfo(randomX, randomY, targetBackground, matrixTemplate, param, templateImages, resourceImage);
|
||||
} finally {
|
||||
// 使用完后关闭流
|
||||
for (InputStream inputStream : inputStreams) {
|
||||
@@ -127,14 +131,16 @@ public class StandardSliderImageCaptchaGenerator extends AbstractImageCaptchaGen
|
||||
int randomY,
|
||||
BufferedImage backgroundImage,
|
||||
BufferedImage sliderImage,
|
||||
GenerateParam param) {
|
||||
String backgroundFormatName = param.getBackgroundFormatName();
|
||||
String sliderFormatName = param.getSliderFormatName();
|
||||
String backGroundImageBase64 = getImageTransform().transform(backgroundImage, backgroundFormatName);
|
||||
String sliderImageBase64 = getImageTransform().transform(sliderImage, sliderFormatName);
|
||||
GenerateParam param,
|
||||
ResourceMap templateResource,
|
||||
Resource resourceImage) {
|
||||
ImageTransformData transform = getImageTransform().transform(param, backgroundImage, sliderImage, resourceImage, templateResource);
|
||||
|
||||
return SliderImageCaptchaInfo.of(randomX, randomY,
|
||||
backGroundImageBase64,
|
||||
sliderImageBase64,
|
||||
transform.getBackgroundImageUrl(),
|
||||
transform.getTemplateImageUrl(),
|
||||
resourceImage.getTag(),
|
||||
templateResource.getTag(),
|
||||
backgroundImage.getWidth(), backgroundImage.getHeight(),
|
||||
sliderImage.getWidth(), sliderImage.getHeight()
|
||||
);
|
||||
@@ -158,14 +164,14 @@ public class StandardSliderImageCaptchaGenerator extends AbstractImageCaptchaGen
|
||||
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_RESOURCE_PATH.concat("/1.jpg")));
|
||||
|
||||
// 添加一些系统的 模板文件
|
||||
Map<String, Resource> template1 = new HashMap<>(4);
|
||||
ResourceMap template1 = new ResourceMap(DEFAULT_TAG, 4);
|
||||
template1.put(SliderCaptchaConstant.TEMPLATE_ACTIVE_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/1/active.png")));
|
||||
template1.put(SliderCaptchaConstant.TEMPLATE_FIXED_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/1/fixed.png")));
|
||||
template1.put(SliderCaptchaConstant.TEMPLATE_MATRIX_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/1/matrix.png")));
|
||||
resourceStore.addTemplate(CaptchaTypeConstant.SLIDER, template1);
|
||||
|
||||
|
||||
Map<String, Resource> template2 = new HashMap<>(4);
|
||||
ResourceMap template2 = new ResourceMap(DEFAULT_TAG, 4);
|
||||
template2.put(SliderCaptchaConstant.TEMPLATE_ACTIVE_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/2/active.png")));
|
||||
template2.put(SliderCaptchaConstant.TEMPLATE_FIXED_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/2/fixed.png")));
|
||||
template2.put(SliderCaptchaConstant.TEMPLATE_MATRIX_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/2/matrix.png")));
|
||||
|
||||
+15
-1
@@ -1,8 +1,11 @@
|
||||
package cloud.tianai.captcha.generator.impl.transform;
|
||||
|
||||
import cloud.tianai.captcha.generator.ImageTransform;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.GenerateParam;
|
||||
import cloud.tianai.captcha.generator.common.model.dto.ImageTransformData;
|
||||
import cloud.tianai.captcha.generator.common.util.CaptchaImageUtils;
|
||||
import cloud.tianai.captcha.generator.common.util.ImgWriter;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
@@ -18,7 +21,6 @@ import java.util.Base64;
|
||||
*/
|
||||
public class Base64ImageTransform implements ImageTransform {
|
||||
|
||||
@Override
|
||||
@SneakyThrows(IOException.class)
|
||||
public String transform(BufferedImage bufferedImage, String transformType) {
|
||||
// 这里判断处理一下,加一些警告日志
|
||||
@@ -55,4 +57,16 @@ public class Base64ImageTransform implements ImageTransform {
|
||||
// 其它的暂时不考虑
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageTransformData transform(GenerateParam param, BufferedImage backgroundImage, BufferedImage templateImage, Object backgroundResource, Object templateResource) {
|
||||
ImageTransformData imageTransformData = new ImageTransformData();
|
||||
if (backgroundImage != null) {
|
||||
imageTransformData.setBackgroundImageUrl(transform(backgroundImage, param.getBackgroundFormatName()));
|
||||
}
|
||||
if (templateImage != null) {
|
||||
imageTransformData.setTemplateImageUrl(transform(templateImage, param.getTemplateFormatName()));
|
||||
}
|
||||
return imageTransformData;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ public abstract class AbstractResourceProvider implements ResourceProvider {
|
||||
public InputStream getResourceInputStream(Resource data) {
|
||||
InputStream resourceInputStream = doGetResourceInputStream(data);
|
||||
if (resourceInputStream == null) {
|
||||
throw new IllegalArgumentException("滑块验证码无法读到指定的资源[" + getName() + "]" + data);
|
||||
throw new IllegalArgumentException("无法读到指定的资源[" + getName() + "]" + data);
|
||||
}
|
||||
return resourceInputStream;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package cloud.tianai.captcha.resource;
|
||||
|
||||
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.ResourceMap;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author: 天爱有情
|
||||
@@ -17,17 +17,19 @@ public interface ImageCaptchaResourceManager {
|
||||
* 随机获取某个模板
|
||||
*
|
||||
* @param type 验证码类型
|
||||
* @param tag 二级过滤,可以为空
|
||||
* @return Map<String, Resource>
|
||||
*/
|
||||
Map<String, Resource> randomGetTemplate(String type);
|
||||
ResourceMap randomGetTemplate(String type, String tag);
|
||||
|
||||
/**
|
||||
* 随机获取某个资源对象
|
||||
*
|
||||
* @param type 验证码类型
|
||||
* @param tag 二级过滤,可以为空
|
||||
* @return Resource
|
||||
*/
|
||||
Resource randomGetResource(String type);
|
||||
Resource randomGetResource(String type, String tag);
|
||||
|
||||
/**
|
||||
* 获取真正的资源流通过资源对象
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package cloud.tianai.captcha.resource;
|
||||
|
||||
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.ResourceMap;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -21,55 +20,6 @@ public interface ResourceStore {
|
||||
*/
|
||||
void addResource(String type, Resource resource);
|
||||
|
||||
/**
|
||||
* 清除某个类型下的所有资源
|
||||
*
|
||||
* @param type type
|
||||
*/
|
||||
void clearResources(String type);
|
||||
|
||||
/**
|
||||
* 清除所有资源
|
||||
*/
|
||||
void clearAllResources();
|
||||
|
||||
/**
|
||||
* 获取所有资源对象
|
||||
*
|
||||
* @return List<Resource>
|
||||
*/
|
||||
Map<String, List<Resource>> listAllResources();
|
||||
|
||||
/**
|
||||
* 获取某个type下的所有资源对象
|
||||
*
|
||||
* @param type type
|
||||
* @return List<Resource>
|
||||
*/
|
||||
List<Resource> listResourcesByType(String type);
|
||||
|
||||
/**
|
||||
* 随机获取某个资源
|
||||
*
|
||||
* @param type type
|
||||
* @return Resource
|
||||
*/
|
||||
Resource randomGetResource(String type);
|
||||
|
||||
/**
|
||||
* 获取资源总数
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int getAllResourceCount();
|
||||
|
||||
/**
|
||||
* 获取某个type下的资源总数
|
||||
*
|
||||
* @param type type
|
||||
* @return int
|
||||
*/
|
||||
int getResourceCount(String type);
|
||||
|
||||
/**
|
||||
* 添加模板
|
||||
@@ -77,34 +27,15 @@ public interface ResourceStore {
|
||||
* @param type 验证码类型
|
||||
* @param template 模板
|
||||
*/
|
||||
void addTemplate(String type, Map<String, Resource> template);
|
||||
void addTemplate(String type, ResourceMap template);
|
||||
|
||||
/**
|
||||
* 清除所有模板
|
||||
*/
|
||||
void clearAllTemplates();
|
||||
|
||||
/**
|
||||
* 清除某个type下的所有模板
|
||||
* 随机获取某个资源
|
||||
*
|
||||
* @param type type
|
||||
* @return Resource
|
||||
*/
|
||||
void clearTemplates(String type);
|
||||
|
||||
/**
|
||||
* 获取所有模板通过type
|
||||
*
|
||||
* @param type 验证码类型
|
||||
* @return List<Map < String, Resource>>
|
||||
*/
|
||||
List<Map<String, Resource>> listTemplatesByType(String type);
|
||||
|
||||
/**
|
||||
* 获取所有模板
|
||||
*
|
||||
* @return Map<String, List < Map < String, Resource>>>
|
||||
*/
|
||||
Map<String, List<Map<String, Resource>>> listAllTemplates();
|
||||
Resource randomGetResourceByTypeAndTag(String type, String tag);
|
||||
|
||||
/**
|
||||
* 随机获取某个模板通过type
|
||||
@@ -112,6 +43,6 @@ public interface ResourceStore {
|
||||
* @param type type
|
||||
* @return Map<String, Resource>
|
||||
*/
|
||||
Map<String, Resource> randomGetTemplateByType(String type);
|
||||
ResourceMap randomGetTemplateByTypeAndTag(String type, String tag);
|
||||
|
||||
}
|
||||
|
||||
@@ -10,10 +10,22 @@ import lombok.Data;
|
||||
* @Description 资源对象
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class Resource {
|
||||
/** 类型. */
|
||||
private String type;
|
||||
/** 数据,传输给 {@link ResourceProvider} 的参数 */
|
||||
public String data;
|
||||
/** 标签.*/
|
||||
private String tag;
|
||||
|
||||
public Resource(String type, String data) {
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Resource(String type, String data, String tag) {
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
this.tag = tag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package cloud.tianai.captcha.resource.common.model.dto;
|
||||
|
||||
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* @Author: 天爱有情
|
||||
* @date 2022/12/30 9:23
|
||||
* @Description 存储一组Resource的Map, 增加tag标记
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ResourceMap extends HashMap<String, Resource> {
|
||||
|
||||
private String tag;
|
||||
|
||||
public ResourceMap(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public ResourceMap(String tag, int initialCapacity) {
|
||||
super(initialCapacity);
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public ResourceMap(int initialCapacity) {
|
||||
super(initialCapacity);
|
||||
}
|
||||
|
||||
public ResourceMap() {
|
||||
}
|
||||
}
|
||||
+5
-4
@@ -1,6 +1,7 @@
|
||||
package cloud.tianai.captcha.resource.impl;
|
||||
|
||||
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.ResourceMap;
|
||||
import cloud.tianai.captcha.resource.impl.provider.URLResourceProvider;
|
||||
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
|
||||
import cloud.tianai.captcha.resource.ResourceProvider;
|
||||
@@ -49,8 +50,8 @@ public class DefaultImageCaptchaResourceManager implements ImageCaptchaResourceM
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Resource> randomGetTemplate(String type) {
|
||||
Map<String, Resource> resourceMap = resourceStore.randomGetTemplateByType(type);
|
||||
public ResourceMap randomGetTemplate(String type, String tag) {
|
||||
ResourceMap resourceMap = resourceStore.randomGetTemplateByTypeAndTag(type, tag);
|
||||
if (resourceMap == null) {
|
||||
throw new IllegalStateException("随机获取模板错误,store中模板为空, type:" + type);
|
||||
}
|
||||
@@ -58,8 +59,8 @@ public class DefaultImageCaptchaResourceManager implements ImageCaptchaResourceM
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource randomGetResource(String type) {
|
||||
Resource resource = resourceStore.randomGetResource(type);
|
||||
public Resource randomGetResource(String type, String tag) {
|
||||
Resource resource = resourceStore.randomGetResourceByTypeAndTag(type, tag);
|
||||
if (resource == null) {
|
||||
throw new IllegalStateException("随机获取资源错误,store中资源为空, type:" + type);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package cloud.tianai.captcha.resource.impl;
|
||||
|
||||
import cloud.tianai.captcha.common.util.CollectionUtils;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
||||
import cloud.tianai.captcha.common.util.CollectionUtils;
|
||||
import cloud.tianai.captcha.common.util.ObjectUtils;
|
||||
import cloud.tianai.captcha.resource.ResourceStore;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
||||
import cloud.tianai.captcha.resource.common.model.dto.ResourceMap;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
@@ -15,44 +15,47 @@ import java.util.concurrent.ThreadLocalRandom;
|
||||
* @Description 默认的资源存储
|
||||
*/
|
||||
public class DefaultResourceStore implements ResourceStore {
|
||||
private static final String TYPE_TAG_SPLIT_FLAG = "|";
|
||||
/**
|
||||
* 模板资源.
|
||||
*/
|
||||
private Map<String, List<Map<String, Resource>>> templateResourceMap = new HashMap<>(2);
|
||||
private Map<String, List<ResourceMap>> templateResourceMap = new HashMap<>(2);
|
||||
|
||||
/**
|
||||
* resource.
|
||||
*/
|
||||
private Map<String, List<Resource>> resourceMap = new HashMap<>(2);
|
||||
|
||||
/** 用于检索 type和tag. */
|
||||
private Map<String, List<ResourceMap>> templateResourceTagMap = new HashMap<>(2);
|
||||
private Map<String, List<Resource>> resourceTagMap = new HashMap<>(2);
|
||||
|
||||
@Override
|
||||
public void addResource(String type, Resource resource) {
|
||||
resourceMap.computeIfAbsent(type, k -> new ArrayList<>(20)).add(resource);
|
||||
// 添加tag标签字典
|
||||
if (!ObjectUtils.isEmpty(resource.getTag())) {
|
||||
resourceTagMap.computeIfAbsent(mergeTypeAndTag(type, resource.getTag()), k -> new ArrayList<>(20)).add(resource);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearResources(String type) {
|
||||
resourceMap.remove(type);
|
||||
public void addTemplate(String type, ResourceMap template) {
|
||||
templateResourceMap.computeIfAbsent(type, k -> new ArrayList<>(2)).add(template);
|
||||
// 添加tag标签字典
|
||||
if (!ObjectUtils.isEmpty(template.getTag())) {
|
||||
templateResourceTagMap.computeIfAbsent(mergeTypeAndTag(type, template.getTag()), k -> new ArrayList<>(2)).add(template);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAllResources() {
|
||||
resourceMap.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<Resource>> listAllResources() {
|
||||
return resourceMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Resource> listResourcesByType(String type) {
|
||||
return resourceMap.getOrDefault(type, Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource randomGetResource(String type) {
|
||||
List<Resource> resources = resourceMap.get(type);
|
||||
public Resource randomGetResourceByTypeAndTag(String type, String tag) {
|
||||
List<Resource> resources;
|
||||
if (ObjectUtils.isEmpty(tag)) {
|
||||
resources = resourceMap.get(type);
|
||||
} else {
|
||||
resources = resourceTagMap.get(mergeTypeAndTag(type, tag));
|
||||
}
|
||||
if (CollectionUtils.isEmpty(resources)) {
|
||||
throw new IllegalStateException("随机获取资源错误,store中资源为空, type:" + type);
|
||||
}
|
||||
@@ -64,48 +67,13 @@ public class DefaultResourceStore implements ResourceStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAllResourceCount() {
|
||||
int count = 0;
|
||||
for (List<Resource> value : resourceMap.values()) {
|
||||
count += value.size();
|
||||
public ResourceMap randomGetTemplateByTypeAndTag(String type, String tag) {
|
||||
List<ResourceMap> templateList;
|
||||
if (ObjectUtils.isEmpty(tag)) {
|
||||
templateList = templateResourceMap.get(type);
|
||||
} else {
|
||||
templateList = templateResourceTagMap.get(mergeTypeAndTag(type, tag));
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResourceCount(String type) {
|
||||
return resourceMap.getOrDefault(type, Collections.emptyList()).size();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addTemplate(String type, Map<String, Resource> template) {
|
||||
templateResourceMap.computeIfAbsent(type, k -> new ArrayList<>(2)).add(template);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAllTemplates() {
|
||||
templateResourceMap.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearTemplates(String type) {
|
||||
templateResourceMap.remove(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Resource>> listTemplatesByType(String type) {
|
||||
return templateResourceMap.getOrDefault(type, Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<Map<String, Resource>>> listAllTemplates() {
|
||||
return templateResourceMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Resource> randomGetTemplateByType(String type) {
|
||||
List<Map<String, Resource>> templateList = templateResourceMap.get(type);
|
||||
if (CollectionUtils.isEmpty(templateList)) {
|
||||
throw new IllegalStateException("随机获取模板错误,store中模板为空, type:" + type);
|
||||
}
|
||||
@@ -117,4 +85,55 @@ public class DefaultResourceStore implements ResourceStore {
|
||||
return templateList.get(randomIndex);
|
||||
}
|
||||
|
||||
public String mergeTypeAndTag(String type, String tag) {
|
||||
return type + TYPE_TAG_SPLIT_FLAG + tag;
|
||||
}
|
||||
|
||||
|
||||
public void clearResources(String type) {
|
||||
resourceMap.remove(type);
|
||||
}
|
||||
|
||||
public void clearAllResources() {
|
||||
resourceMap.clear();
|
||||
}
|
||||
|
||||
public Map<String, List<Resource>> listAllResources() {
|
||||
return resourceMap;
|
||||
}
|
||||
|
||||
public List<Resource> listResourcesByType(String type) {
|
||||
return resourceMap.getOrDefault(type, Collections.emptyList());
|
||||
}
|
||||
|
||||
public int getAllResourceCount() {
|
||||
int count = 0;
|
||||
for (List<Resource> value : resourceMap.values()) {
|
||||
count += value.size();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public int getResourceCount(String type) {
|
||||
return resourceMap.getOrDefault(type, Collections.emptyList()).size();
|
||||
}
|
||||
|
||||
|
||||
public void clearAllTemplates() {
|
||||
templateResourceMap.clear();
|
||||
}
|
||||
|
||||
public void clearTemplates(String type) {
|
||||
templateResourceMap.remove(type);
|
||||
}
|
||||
|
||||
public List<ResourceMap> listTemplatesByType(String type) {
|
||||
return templateResourceMap.getOrDefault(type, Collections.emptyList());
|
||||
}
|
||||
|
||||
public Map<String, List<ResourceMap>> listAllTemplates() {
|
||||
return templateResourceMap;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -122,8 +122,8 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
|
||||
ClickImageCheckDefinition definition = clickImageCheckDefinitionList.get(i);
|
||||
Integer x = definition.getX();
|
||||
Integer y = definition.getY();
|
||||
Integer width = imageCaptchaInfo.getBgImageWidth();
|
||||
Integer height = imageCaptchaInfo.getBgImageHeight();
|
||||
Integer width = imageCaptchaInfo.getBackgroundImageWidth();
|
||||
Integer height = imageCaptchaInfo.getBackgroundImageHeight();
|
||||
float vx = calcPercentage(x, width);
|
||||
float vy = calcPercentage(y, height);
|
||||
sb.append(vx).append(",").append(vy).append(";");
|
||||
@@ -327,8 +327,8 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
|
||||
return defaultData;
|
||||
}
|
||||
|
||||
protected void addPercentage(ImageCaptchaInfo imageCaptchaInfo, Map<String, Object> sliderCaptchaValidData) {
|
||||
float percentage = calcPercentage(imageCaptchaInfo.getRandomX(), imageCaptchaInfo.getBgImageWidth());
|
||||
sliderCaptchaValidData.put(PERCENTAGE_KEY, percentage);
|
||||
protected void addPercentage(ImageCaptchaInfo imageCaptchaInfo, Map<String, Object> imageCaptchaValidData) {
|
||||
float percentage = calcPercentage(imageCaptchaInfo.getRandomX(), imageCaptchaInfo.getBackgroundImageWidth());
|
||||
imageCaptchaValidData.put(PERCENTAGE_KEY, percentage);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user