diff --git a/pom.xml b/pom.xml
index ca982a8..fc3576c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
cloud.tianai.captcha
tianai-captcha
- 1.3.3
+ 1.3.3.1
tianai-captcha
行为验证码
diff --git a/src/main/java/cloud/tianai/captcha/common/constant/CommonConstant.java b/src/main/java/cloud/tianai/captcha/common/constant/CommonConstant.java
new file mode 100644
index 0000000..c6ac1d7
--- /dev/null
+++ b/src/main/java/cloud/tianai/captcha/common/constant/CommonConstant.java
@@ -0,0 +1,8 @@
+package cloud.tianai.captcha.common.constant;
+
+public interface CommonConstant {
+
+ String DEFAULT_TAG = "default";
+ /** 图标点选资源存储类型.*/
+ String IMAGE_CLICK_ICON = "ICON";
+}
diff --git a/src/main/java/cloud/tianai/captcha/generator/AbstractImageCaptchaGenerator.java b/src/main/java/cloud/tianai/captcha/generator/AbstractImageCaptchaGenerator.java
index e6dd37b..5bef908 100644
--- a/src/main/java/cloud/tianai/captcha/generator/AbstractImageCaptchaGenerator.java
+++ b/src/main/java/cloud/tianai/captcha/generator/AbstractImageCaptchaGenerator.java
@@ -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 requiredRandomGetTemplate(String type) {
- Map 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 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 inputStreams) {
+ InputStream stream = getImageResourceManager().getResourceInputStream(resource);
+ if (stream != null && inputStreams != null) {
+ inputStreams.add(stream);
+ }
+ return stream;
+ }
+
+ protected Optional getTemplateImageOfOptional(Map templateImages, String imageName) {
+ Optional 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 getTemplateFileOfOptional(Map 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) {
diff --git a/src/main/java/cloud/tianai/captcha/generator/ImageTransform.java b/src/main/java/cloud/tianai/captcha/generator/ImageTransform.java
index eb50b71..e9176a3 100644
--- a/src/main/java/cloud/tianai/captcha/generator/ImageTransform.java
+++ b/src/main/java/cloud/tianai/captcha/generator/ImageTransform.java
@@ -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);
}
diff --git a/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ClickImageCheckDefinition.java b/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ClickImageCheckDefinition.java
index 8679266..772e461 100644
--- a/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ClickImageCheckDefinition.java
+++ b/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ClickImageCheckDefinition.java
@@ -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;
-}
\ No newline at end of file
+}
diff --git a/src/main/java/cloud/tianai/captcha/generator/common/model/dto/GenerateParam.java b/src/main/java/cloud/tianai/captcha/generator/common/model/dto/GenerateParam.java
index de44c50..76eb763 100644
--- a/src/main/java/cloud/tianai/captcha/generator/common/model/dto/GenerateParam.java
+++ b/src/main/java/cloud/tianai/captcha/generator/common/model/dto/GenerateParam.java
@@ -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;
}
diff --git a/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ImageCaptchaInfo.java b/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ImageCaptchaInfo.java
index e2590a3..04cff2d 100644
--- a/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ImageCaptchaInfo.java
+++ b/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ImageCaptchaInfo.java
@@ -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);
}
}
diff --git a/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ImageTransformData.java b/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ImageTransformData.java
new file mode 100644
index 0000000..0dcc2c5
--- /dev/null
+++ b/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ImageTransformData.java
@@ -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;
+ }
+}
diff --git a/src/main/java/cloud/tianai/captcha/generator/common/model/dto/RotateImageCaptchaInfo.java b/src/main/java/cloud/tianai/captcha/generator/common/model/dto/RotateImageCaptchaInfo.java
index a1f7abe..b5b465d 100644
--- a/src/main/java/cloud/tianai/captcha/generator/common/model/dto/RotateImageCaptchaInfo.java
+++ b/src/main/java/cloud/tianai/captcha/generator/common/model/dto/RotateImageCaptchaInfo.java
@@ -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;
diff --git a/src/main/java/cloud/tianai/captcha/generator/common/model/dto/SliderImageCaptchaInfo.java b/src/main/java/cloud/tianai/captcha/generator/common/model/dto/SliderImageCaptchaInfo.java
index 8ece69f..7455128 100644
--- a/src/main/java/cloud/tianai/captcha/generator/common/model/dto/SliderImageCaptchaInfo.java
+++ b/src/main/java/cloud/tianai/captcha/generator/common/model/dto/SliderImageCaptchaInfo.java
@@ -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;
}
diff --git a/src/main/java/cloud/tianai/captcha/generator/impl/AbstractClickImageCaptchaGenerator.java b/src/main/java/cloud/tianai/captcha/generator/impl/AbstractClickImageCaptchaGenerator.java
index 6301c51..cf1fb17 100644
--- a/src/main/java/cloud/tianai/captcha/generator/impl/AbstractClickImageCaptchaGenerator.java
+++ b/src/main/java/cloud/tianai/captcha/generator/impl/AbstractClickImageCaptchaGenerator.java
@@ -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 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 clickImageCheckDefinitionList = new ArrayList<>(interferenceCount);
- int allImages = interferenceCount + checkClickCount;
- int avg = bgImage.getWidth() / allImages;
- List 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 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 imgTips = randomGetClickImgTips(param);
+ int allImages = imgTips.size();
+ List 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 checkClickImageCheckDefinitionList = filterAndSortClickImageCheckDefinition(clickImageCheckDefinitionList);
+ // wrap
+ return wrapClickImageCaptchaInfo(param, bgImage, checkClickImageCheckDefinitionList, resourceImage);
+
}
/**
- * 从总的图片中 去除要校验的图片数据 以及顺序
+ * 过滤并排序校验的图片点选顺序
*
* @param allCheckDefinitionList 总的点选图片
- * @param checkClickCount 参与校验的数据
* @return List
*/
- protected List getCheckClickImageCheckDefinitionList(List allCheckDefinitionList,
- Integer checkClickCount) {
- // 打乱
- Collections.shuffle(allCheckDefinitionList);
- // 拿出参与校验的数据
- List checkClickImageCheckDefinitionList = new ArrayList<>(checkClickCount);
- for (int i = 0; i < checkClickCount; i++) {
- ClickImageCheckDefinition clickImageCheckDefinition = allCheckDefinitionList.get(i);
- checkClickImageCheckDefinitionList.add(clickImageCheckDefinition);
- }
- return checkClickImageCheckDefinitionList;
- }
+ protected abstract List filterAndSortClickImageCheckDefinition(List allCheckDefinitionList);
/**
* 随机获取一组数据用于生成随机图
*
- * @param tipSize tipSize
* @return List
*/
- protected abstract List randomGetClickImgTips(int tipSize);
+ protected abstract List 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 checkClickImageCheckDefinitionList);
+ List checkClickImageCheckDefinitionList, Resource resourceImage);
/**
* @Author: 天爱有情
@@ -157,6 +125,6 @@ public abstract class AbstractClickImageCaptchaGenerator extends AbstractImageCa
/** 图片. */
private BufferedImage image;
/** 提示. */
- private String tip;
+ private Resource tip;
}
}
diff --git a/src/main/java/cloud/tianai/captcha/generator/impl/CacheImageCaptchaGenerator.java b/src/main/java/cloud/tianai/captcha/generator/impl/CacheImageCaptchaGenerator.java
index de828fa..3d5ee13 100644
--- a/src/main/java/cloud/tianai/captcha/generator/impl/CacheImageCaptchaGenerator.java
+++ b/src/main/java/cloud/tianai/captcha/generator/impl/CacheImageCaptchaGenerator.java
@@ -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
diff --git a/src/main/java/cloud/tianai/captcha/generator/impl/StandardConcatImageCaptchaGenerator.java b/src/main/java/cloud/tianai/captcha/generator/impl/StandardConcatImageCaptchaGenerator.java
index d1387f1..9576b3e 100644
--- a/src/main/java/cloud/tianai/captcha/generator/impl/StandardConcatImageCaptchaGenerator.java
+++ b/src/main/java/cloud/tianai/captcha/generator/impl/StandardConcatImageCaptchaGenerator.java
@@ -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 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(),
diff --git a/src/main/java/cloud/tianai/captcha/generator/impl/StandardRandomWordClickImageCaptchaGenerator.java b/src/main/java/cloud/tianai/captcha/generator/impl/StandardRandomWordClickImageCaptchaGenerator.java
index 52e7b7b..5414355 100644
--- a/src/main/java/cloud/tianai/captcha/generator/impl/StandardRandomWordClickImageCaptchaGenerator.java
+++ b/src/main/java/cloud/tianai/captcha/generator/impl/StandardRandomWordClickImageCaptchaGenerator.java
@@ -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 randomGetClickImgTips(int tipSize) {
+ protected List randomGetClickImgTips(GenerateParam param) {
+ int tipSize = interferenceCount + checkClickCount;
ThreadLocalRandom random = ThreadLocalRandom.current();
- List tipList = new ArrayList<>(tipSize);
+ List 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 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 filterAndSortClickImageCheckDefinition(List allCheckDefinitionList) {
+ // 打乱
+ Collections.shuffle(allCheckDefinitionList);
+ // 拿出参与校验的数据
+ List 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 checkClickImageCheckDefinitionList) {
+ List 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);
diff --git a/src/main/java/cloud/tianai/captcha/generator/impl/StandardRotateImageCaptchaGenerator.java b/src/main/java/cloud/tianai/captcha/generator/impl/StandardRotateImageCaptchaGenerator.java
index f5288ec..b826770 100644
--- a/src/main/java/cloud/tianai/captcha/generator/impl/StandardRotateImageCaptchaGenerator.java
+++ b/src/main/java/cloud/tianai/captcha/generator/impl/StandardRotateImageCaptchaGenerator.java
@@ -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 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 templateImages = requiredRandomGetTemplate(param.getType());
+ ResourceMap templateImages = requiredRandomGetTemplate(param.getType(), param.getTemplateImageTag());
Collection 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()
);
diff --git a/src/main/java/cloud/tianai/captcha/generator/impl/StandardSliderImageCaptchaGenerator.java b/src/main/java/cloud/tianai/captcha/generator/impl/StandardSliderImageCaptchaGenerator.java
index 92c23de..1ae1cf4 100644
--- a/src/main/java/cloud/tianai/captcha/generator/impl/StandardSliderImageCaptchaGenerator.java
+++ b/src/main/java/cloud/tianai/captcha/generator/impl/StandardSliderImageCaptchaGenerator.java
@@ -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 templateImages = requiredRandomGetTemplate(param.getType());
+ ResourceMap templateImages = requiredRandomGetTemplate(param.getType(), param.getTemplateImageTag());
Collection 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 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 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")));
diff --git a/src/main/java/cloud/tianai/captcha/generator/impl/transform/Base64ImageTransform.java b/src/main/java/cloud/tianai/captcha/generator/impl/transform/Base64ImageTransform.java
index 80c5f55..eb293c6 100644
--- a/src/main/java/cloud/tianai/captcha/generator/impl/transform/Base64ImageTransform.java
+++ b/src/main/java/cloud/tianai/captcha/generator/impl/transform/Base64ImageTransform.java
@@ -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;
+ }
}
diff --git a/src/main/java/cloud/tianai/captcha/resource/AbstractResourceProvider.java b/src/main/java/cloud/tianai/captcha/resource/AbstractResourceProvider.java
index 4999dda..a2236d8 100644
--- a/src/main/java/cloud/tianai/captcha/resource/AbstractResourceProvider.java
+++ b/src/main/java/cloud/tianai/captcha/resource/AbstractResourceProvider.java
@@ -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;
}
diff --git a/src/main/java/cloud/tianai/captcha/resource/ImageCaptchaResourceManager.java b/src/main/java/cloud/tianai/captcha/resource/ImageCaptchaResourceManager.java
index f4625f7..6ff62d9 100644
--- a/src/main/java/cloud/tianai/captcha/resource/ImageCaptchaResourceManager.java
+++ b/src/main/java/cloud/tianai/captcha/resource/ImageCaptchaResourceManager.java
@@ -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
*/
- Map 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);
/**
* 获取真正的资源流通过资源对象
diff --git a/src/main/java/cloud/tianai/captcha/resource/ResourceStore.java b/src/main/java/cloud/tianai/captcha/resource/ResourceStore.java
index 9727507..63c73f7 100644
--- a/src/main/java/cloud/tianai/captcha/resource/ResourceStore.java
+++ b/src/main/java/cloud/tianai/captcha/resource/ResourceStore.java
@@ -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
- */
- Map> listAllResources();
-
- /**
- * 获取某个type下的所有资源对象
- *
- * @param type type
- * @return List
- */
- List 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 template);
+ void addTemplate(String type, ResourceMap template);
/**
- * 清除所有模板
- */
- void clearAllTemplates();
-
- /**
- * 清除某个type下的所有模板
+ * 随机获取某个资源
*
* @param type type
+ * @return Resource
*/
- void clearTemplates(String type);
-
- /**
- * 获取所有模板通过type
- *
- * @param type 验证码类型
- * @return List