diff --git a/pom.xml b/pom.xml
index f2ef225..ef46c0a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
cloud.tianai.captcha
tianai-captcha
- 1.3.0.RELEASE
+ 1.3.1.alpha
tianai-captcha
滑块验证码
diff --git a/readme.md b/readme.md
index 1be5526..329fdeb 100644
--- a/readme.md
+++ b/readme.md
@@ -34,15 +34,15 @@
### 2. 使用 `SliderCaptchaGenerator`生成器生成滑块验证码
```java
-import cloud.tianai.captcha.template.slider.generator.impl.StandardImageCaptchaGenerator;
+import cloud.tianai.captcha.template.slider.generator.impl.StandardSliderImageCaptchaGenerator;
import cloud.tianai.captcha.template.slider.generator.impl.StandardSliderCaptchaGenerator;
-import cloud.tianai.captcha.template.slider.resource.SliderCaptchaResourceManager;
-import cloud.tianai.captcha.template.slider.resource.impl.DefaultSliderCaptchaResourceManager;
+import cloud.tianai.captcha.template.slider.resource.ImageCaptchaResourceManager;
+import cloud.tianai.captcha.template.slider.resource.impl.DefaultImageCaptchaResourceManager;
public class Test {
public static void main(String[] args) throws InterruptedException {
- SliderCaptchaResourceManager sliderCaptchaResourceManager = new DefaultSliderCaptchaResourceManager();
- StandardImageCaptchaGenerator sliderCaptchaGenerator = new StandardImageCaptchaGenerator(sliderCaptchaResourceManager, true);
+ ImageCaptchaResourceManager imageCaptchaResourceManager = new DefaultImageCaptchaResourceManager();
+ StandardSliderImageCaptchaGenerator sliderCaptchaGenerator = new StandardSliderImageCaptchaGenerator(imageCaptchaResourceManager, true);
// 生成滑块图片
SliderCaptchaInfo slideImageInfo = sliderCaptchaGenerator.generateCaptchaImage();
System.out.println(slideImageInfo);
@@ -101,9 +101,9 @@ public class Test2 {
public class Test {
public static void main(String[] args) {
// 资源管理器
- SliderCaptchaResourceManager sliderCaptchaResourceManager = new DefaultSliderCaptchaResourceManager();
+ SliderCaptchaResourceManager imageCaptchaResourceManager = new DefaultSliderCaptchaResourceManager();
// 标准验证码生成器
- StandardSliderCaptchaGenerator sliderCaptchaGenerator = new StandardSliderCaptchaGenerator(sliderCaptchaResourceManager, true);
+ StandardSliderCaptchaGenerator sliderCaptchaGenerator = new StandardSliderCaptchaGenerator(imageCaptchaResourceManager, true);
// 生成滑块图片
SliderCaptchaInfo slideImageInfo = sliderCaptchaGenerator.generateSlideImageInfo(GenerateParam.builder()
.sliderFormatName("jpeg")
@@ -121,9 +121,9 @@ public class Test {
public class Test {
public static void main(String[] args) {
// 资源管理器
- SliderCaptchaResourceManager sliderCaptchaResourceManager = new DefaultSliderCaptchaResourceManager();
+ SliderCaptchaResourceManager imageCaptchaResourceManager = new DefaultSliderCaptchaResourceManager();
// 标准验证码生成器
- StandardSliderCaptchaGenerator sliderCaptchaGenerator = new StandardSliderCaptchaGenerator(sliderCaptchaResourceManager, true);
+ StandardSliderCaptchaGenerator sliderCaptchaGenerator = new StandardSliderCaptchaGenerator(imageCaptchaResourceManager, true);
// 生成滑块图片
SliderCaptchaInfo slideImageInfo = sliderCaptchaGenerator.generateSlideImageInfo(GenerateParam.builder()
.sliderFormatName("webp")
@@ -143,7 +143,7 @@ public class Test {
public class Test {
public static void main(String[] args) {
// 通过资源管理器或者资源存储器
- ResourceStore resourceStore = sliderCaptchaResourceManager.getResourceStore();
+ ResourceStore resourceStore = imageCaptchaResourceManager.getResourceStore();
// 添加classpath目录下的 aa.jpg 图片
resourceStore.addResource(new Resource(ClassPathResourceProvider.NAME, "/aa.jpg"));
// 添加远程url图片资源
@@ -165,7 +165,7 @@ public class Test {
public class Test {
public static void main(String[] args) {
// 通过资源管理器或者资源存储器
- ResourceStore resourceStore = sliderCaptchaResourceManager.getResourceStore();
+ ResourceStore resourceStore = imageCaptchaResourceManager.getResourceStore();
// 添加模板.模板图片由三张图片组成
Map template1 = new HashMap<>(4);
template1.put(SliderCaptchaConstant.TEMPLATE_ACTIVE_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, "/active.png"));
@@ -185,7 +185,7 @@ public class Test {
public static void main(String[] args) {
//为方便快速上手 系统本身自带了一张图片和两套滑块模板,如果不想用系统自带的可以不让它加载系统自带的
// 第二个构造参数设置为false时将不加载默认的图片和模板
- SliderCaptchaGenerator sliderCaptchaGenerator = new StandardSliderCaptchaGenerator(sliderCaptchaResourceManager, false);
+ SliderCaptchaGenerator sliderCaptchaGenerator = new StandardSliderCaptchaGenerator(imageCaptchaResourceManager, false);
}
}
```
@@ -207,10 +207,10 @@ public class Test {
public class Test {
public static void main(String[] args) {
// 实现了 ResourceProvider 后
- SliderCaptchaResourceManager sliderCaptchaResourceManager = new DefaultSliderCaptchaResourceManager();
- StandardSliderCaptchaGenerator sliderCaptchaGenerator = new StandardSliderCaptchaGenerator(sliderCaptchaResourceManager, true);
+ SliderCaptchaResourceManager imageCaptchaResourceManager = new DefaultSliderCaptchaResourceManager();
+ StandardSliderCaptchaGenerator sliderCaptchaGenerator = new StandardSliderCaptchaGenerator(imageCaptchaResourceManager, true);
// 注册
- sliderCaptchaResourceManager.registerResourceProvider(new CustomResourceProvider());
+ imageCaptchaResourceManager.registerResourceProvider(new CustomResourceProvider());
}
}
```
@@ -227,8 +227,8 @@ public class Test {
// 参数二: 默认提前缓存多少个
// 参数三: 出错后 等待xx时间再进行生成
// 参数四: 检查时间间隔
- SliderCaptchaResourceManager sliderCaptchaResourceManager = new DefaultSliderCaptchaResourceManager();
- SliderCaptchaGenerator sliderCaptchaGenerator = new CacheSliderCaptchaGenerator(new StandardSliderCaptchaGenerator(sliderCaptchaResourceManager, true), 10, 1000, 100);
+ SliderCaptchaResourceManager imageCaptchaResourceManager = new DefaultSliderCaptchaResourceManager();
+ SliderCaptchaGenerator sliderCaptchaGenerator = new CacheSliderCaptchaGenerator(new StandardSliderCaptchaGenerator(imageCaptchaResourceManager, true), 10, 1000, 100);
// 生成滑块图片
SliderCaptchaInfo slideImageInfo = sliderCaptchaGenerator.generateSlideImageInfo();
// 获取背景图片的base64
diff --git a/src/main/java/cloud/tianai/captcha/template/slider/common/util/CaptchaImageUtils.java b/src/main/java/cloud/tianai/captcha/template/slider/common/util/CaptchaImageUtils.java
index dc3cc95..7b91d32 100644
--- a/src/main/java/cloud/tianai/captcha/template/slider/common/util/CaptchaImageUtils.java
+++ b/src/main/java/cloud/tianai/captcha/template/slider/common/util/CaptchaImageUtils.java
@@ -215,4 +215,14 @@ public class CaptchaImageUtils {
return img;
}
+ public static void centerOverlayAndRotateImage(BufferedImage baseBufferedImage, BufferedImage coverBufferedImage,
+ final double degree) {
+ coverBufferedImage = rotateImage(coverBufferedImage, degree);
+ int bw = baseBufferedImage.getWidth();
+ int bh = baseBufferedImage.getHeight();
+ int cw = coverBufferedImage.getWidth();
+ int ch = coverBufferedImage.getHeight();
+ overlayImage(baseBufferedImage, coverBufferedImage, bw / 2 - cw / 2, bh / 2 - ch / 2);
+ }
+
}
diff --git a/src/main/java/cloud/tianai/captcha/template/slider/generator/AbstractImageCaptchaGenerator.java b/src/main/java/cloud/tianai/captcha/template/slider/generator/AbstractImageCaptchaGenerator.java
index 9e69a35..26ee06a 100644
--- a/src/main/java/cloud/tianai/captcha/template/slider/generator/AbstractImageCaptchaGenerator.java
+++ b/src/main/java/cloud/tianai/captcha/template/slider/generator/AbstractImageCaptchaGenerator.java
@@ -14,7 +14,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import java.util.Map;
-import java.util.concurrent.ThreadLocalRandom;
/**
* @Author: 天爱有情
@@ -71,7 +70,7 @@ public abstract class AbstractImageCaptchaGenerator implements ImageCaptchaGener
if (resource == null) {
throw new IllegalArgumentException("查找模板异常, 该模板下未找到 ".concat(imageName));
}
- return getSlideImageResourceManager().getResourceInputStream(resource);
+ return getImageResourceManager().getResourceInputStream(resource);
}
}
diff --git a/src/main/java/cloud/tianai/captcha/template/slider/generator/ImageCaptchaGenerator.java b/src/main/java/cloud/tianai/captcha/template/slider/generator/ImageCaptchaGenerator.java
index d3489f3..2f4411e 100644
--- a/src/main/java/cloud/tianai/captcha/template/slider/generator/ImageCaptchaGenerator.java
+++ b/src/main/java/cloud/tianai/captcha/template/slider/generator/ImageCaptchaGenerator.java
@@ -3,8 +3,7 @@ package cloud.tianai.captcha.template.slider.generator;
import cloud.tianai.captcha.template.slider.generator.common.constant.CaptchaTypeConstant;
import cloud.tianai.captcha.template.slider.generator.common.model.dto.GenerateParam;
import cloud.tianai.captcha.template.slider.generator.common.model.dto.ImageCaptchaInfo;
-import cloud.tianai.captcha.template.slider.resource.SliderCaptchaResourceManager;
-import cloud.tianai.captcha.template.slider.validator.SliderCaptchaValidator;
+import cloud.tianai.captcha.template.slider.resource.ImageCaptchaResourceManager;
/**
* @Author: 天爱有情
@@ -45,6 +44,6 @@ public interface ImageCaptchaGenerator {
*
* @return SliderCaptchaResourceManager
*/
- SliderCaptchaResourceManager getSlideImageResourceManager();
+ ImageCaptchaResourceManager getImageResourceManager();
}
diff --git a/src/main/java/cloud/tianai/captcha/template/slider/generator/common/model/dto/GenerateParam.java b/src/main/java/cloud/tianai/captcha/template/slider/generator/common/model/dto/GenerateParam.java
index 255bac7..023cb9d 100644
--- a/src/main/java/cloud/tianai/captcha/template/slider/generator/common/model/dto/GenerateParam.java
+++ b/src/main/java/cloud/tianai/captcha/template/slider/generator/common/model/dto/GenerateParam.java
@@ -1,9 +1,7 @@
package cloud.tianai.captcha.template.slider.generator.common.model.dto;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import cloud.tianai.captcha.template.slider.generator.common.constant.CaptchaTypeConstant;
+import lombok.*;
/**
* @Author: 天爱有情
@@ -14,6 +12,7 @@ import lombok.NoArgsConstructor;
@Builder
@NoArgsConstructor
@AllArgsConstructor
+@EqualsAndHashCode
public class GenerateParam {
/** 背景格式化名称.*/
private String backgroundFormatName = "jpeg";
@@ -22,5 +21,5 @@ public class GenerateParam {
/** 是否混淆.*/
private Boolean obfuscate = false;
/** 类型.*/
- private String type;
+ private String type = CaptchaTypeConstant.SLIDER;
}
diff --git a/src/main/java/cloud/tianai/captcha/template/slider/generator/impl/CacheImageCaptchaGenerator.java b/src/main/java/cloud/tianai/captcha/template/slider/generator/impl/CacheImageCaptchaGenerator.java
index 9651a27..b22e8f1 100644
--- a/src/main/java/cloud/tianai/captcha/template/slider/generator/impl/CacheImageCaptchaGenerator.java
+++ b/src/main/java/cloud/tianai/captcha/template/slider/generator/impl/CacheImageCaptchaGenerator.java
@@ -1,19 +1,17 @@
package cloud.tianai.captcha.template.slider.generator.impl;
+import cloud.tianai.captcha.template.slider.common.util.NamedThreadFactory;
import cloud.tianai.captcha.template.slider.generator.ImageCaptchaGenerator;
import cloud.tianai.captcha.template.slider.generator.common.model.dto.GenerateParam;
import cloud.tianai.captcha.template.slider.generator.common.model.dto.ImageCaptchaInfo;
-import cloud.tianai.captcha.template.slider.common.util.NamedThreadFactory;
-import cloud.tianai.captcha.template.slider.resource.SliderCaptchaResourceManager;
+import cloud.tianai.captcha.template.slider.resource.ImageCaptchaResourceManager;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
+import java.util.Map;
+import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -25,29 +23,26 @@ import java.util.concurrent.atomic.AtomicInteger;
public class CacheImageCaptchaGenerator implements ImageCaptchaGenerator {
protected final ScheduledExecutorService scheduledExecutor = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("slider-captcha-queue"));
- protected ConcurrentLinkedQueue queue;
- protected AtomicInteger pos = new AtomicInteger(0);
+ protected Map> queueMap = new ConcurrentHashMap<>(8);
+ protected Map posMap = new ConcurrentHashMap<>(8);
protected ImageCaptchaGenerator target;
protected int size;
/** 等待时间,一般报错或者拉取为空时会休眠一段时间再试. */
protected int waitTime = 1000;
/** 调度器检查缓存的间隔时间. */
protected int period = 100;
- protected GenerateParam generateParam;
@Getter
@Setter
protected boolean requiredGetCaptcha = true;
- public CacheImageCaptchaGenerator(ImageCaptchaGenerator target, GenerateParam generateParam, int size) {
+ public CacheImageCaptchaGenerator(ImageCaptchaGenerator target, int size) {
this.target = target;
- this.generateParam = generateParam;
this.size = size;
}
- public CacheImageCaptchaGenerator(ImageCaptchaGenerator target, GenerateParam generateParam, int size, int waitTime, int period) {
+ public CacheImageCaptchaGenerator(ImageCaptchaGenerator target, int size, int waitTime, int period) {
this.target = target;
- this.generateParam = generateParam;
this.size = size;
this.waitTime = waitTime;
this.period = period;
@@ -62,34 +57,35 @@ public class CacheImageCaptchaGenerator implements ImageCaptchaGenerator {
private void init(int z) {
this.size = z;
- this.pos = new AtomicInteger(0);
- queue = new ConcurrentLinkedQueue<>();
// 初始化一个队列扫描
scheduledExecutor.scheduleAtFixedRate(() -> {
- try {
- while (pos.get() < this.size) {
- if (pos.get() >= size) {
- return;
- }
- ImageCaptchaInfo slideImageInfo = target.generateCaptchaImage(generateParam);
- if (slideImageInfo != null) {
- boolean addStatus = queue.offer(slideImageInfo);
- if (addStatus) {
- // 添加记录
- pos.incrementAndGet();
+ queueMap.forEach((k, queue) -> {
+ try {
+ AtomicInteger pos = posMap.computeIfAbsent(k, k1 -> new AtomicInteger(0));
+ while (pos.get() < this.size) {
+ if (pos.get() >= size) {
+ return;
+ }
+ ImageCaptchaInfo slideImageInfo = target.generateCaptchaImage(k);
+ if (slideImageInfo != null) {
+ boolean addStatus = queue.offer(slideImageInfo);
+ if (addStatus) {
+ // 添加记录
+ pos.incrementAndGet();
+ }
+ } else {
+ sleep();
}
- } else {
- sleep();
}
+ } catch (Exception e) {
+ // cache所有
+ log.error("缓存队列扫描时出错, ex", e);
+ // 休眠
+ sleep();
}
- } catch (Exception e) {
- // cache所有
- log.error("缓存队列扫描时出错, ex", e);
- // 休眠
- sleep();
- }
+ });
+
}, 0, period, TimeUnit.MILLISECONDS);
- log.info("缓存滑块验证码调度器初始化完成: size:{}, genParam:{}", size, generateParam);
}
private void sleep() {
@@ -102,11 +98,14 @@ public class CacheImageCaptchaGenerator implements ImageCaptchaGenerator {
@SneakyThrows
@Override
public ImageCaptchaInfo generateCaptchaImage(String type) {
- return generateCaptchaImage(this.requiredGetCaptcha);
+ GenerateParam generateParam = new GenerateParam();
+ generateParam.setType(type);
+ return generateCaptchaImage(generateParam, this.requiredGetCaptcha);
}
@SneakyThrows
- public ImageCaptchaInfo generateCaptchaImage(boolean requiredGetCaptcha) {
+ public ImageCaptchaInfo generateCaptchaImage(GenerateParam generateParam, boolean requiredGetCaptcha) {
+ ConcurrentLinkedQueue queue = queueMap.computeIfAbsent(generateParam, g -> new ConcurrentLinkedQueue<>());
ImageCaptchaInfo poll = queue.poll();
if (poll == null && requiredGetCaptcha) {
log.warn("滑块验证码缓存不足, genParam:{}", generateParam);
@@ -114,23 +113,32 @@ public class CacheImageCaptchaGenerator implements ImageCaptchaGenerator {
return target.generateCaptchaImage(generateParam);
}
// 减1
- pos.decrementAndGet();
+ if (poll == null) {
+ AtomicInteger pos = posMap.get(generateParam);
+ if (pos != null) {
+ pos.decrementAndGet();
+ }
+ }
return poll;
}
@Override
public ImageCaptchaInfo generateCaptchaImage(String type, String targetFormatName, String matrixFormatName) {
- return target.generateCaptchaImage(type,targetFormatName, matrixFormatName);
+ return generateCaptchaImage(GenerateParam.builder()
+ .type(type)
+ .backgroundFormatName(targetFormatName)
+ .sliderFormatName(matrixFormatName)
+ .build(), true);
}
@Override
public ImageCaptchaInfo generateCaptchaImage(GenerateParam param) {
- return target.generateCaptchaImage(param);
+ return generateCaptchaImage(param, true);
}
@Override
- public SliderCaptchaResourceManager getSlideImageResourceManager() {
- return target.getSlideImageResourceManager();
+ public ImageCaptchaResourceManager getImageResourceManager() {
+ return target.getImageResourceManager();
}
diff --git a/src/main/java/cloud/tianai/captcha/template/slider/generator/impl/MultiImageCaptchaGenerator.java b/src/main/java/cloud/tianai/captcha/template/slider/generator/impl/MultiImageCaptchaGenerator.java
new file mode 100644
index 0000000..9faa162
--- /dev/null
+++ b/src/main/java/cloud/tianai/captcha/template/slider/generator/impl/MultiImageCaptchaGenerator.java
@@ -0,0 +1,64 @@
+package cloud.tianai.captcha.template.slider.generator.impl;
+
+import cloud.tianai.captcha.template.slider.common.util.ObjectUtils;
+import cloud.tianai.captcha.template.slider.generator.AbstractImageCaptchaGenerator;
+import cloud.tianai.captcha.template.slider.generator.ImageCaptchaGenerator;
+import cloud.tianai.captcha.template.slider.generator.common.constant.CaptchaTypeConstant;
+import cloud.tianai.captcha.template.slider.generator.common.model.dto.GenerateParam;
+import cloud.tianai.captcha.template.slider.generator.common.model.dto.ImageCaptchaInfo;
+import cloud.tianai.captcha.template.slider.resource.ImageCaptchaResourceManager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Author: 天爱有情
+ * @date 2022/4/24 9:27
+ * @Description 根据type 匹配对应的验证码生成器
+ */
+public class MultiImageCaptchaGenerator extends AbstractImageCaptchaGenerator {
+
+ private Map imageCaptchaGeneratorMap = new HashMap<>(4);
+
+ private ImageCaptchaResourceManager imageCaptchaResourceManager;
+ private boolean initDefaultResource;
+
+ private String defaultCaptcha = CaptchaTypeConstant.SLIDER;
+ public MultiImageCaptchaGenerator(ImageCaptchaResourceManager imageCaptchaResourceManager, boolean initDefaultResource) {
+ this.imageCaptchaResourceManager = imageCaptchaResourceManager;
+ this.initDefaultResource = initDefaultResource;
+ init();
+ }
+
+ protected void init() {
+ addImageCaptchaGenerator(CaptchaTypeConstant.SLIDER, new StandardSliderImageCaptchaGenerator(imageCaptchaResourceManager, initDefaultResource));
+ addImageCaptchaGenerator(CaptchaTypeConstant.ROTATE, new StandardRotateImageCaptchaGenerator(imageCaptchaResourceManager, initDefaultResource));
+ }
+
+ public void addImageCaptchaGenerator(String key, ImageCaptchaGenerator captchaGenerator) {
+ imageCaptchaGeneratorMap.put(key, captchaGenerator);
+ }
+ public ImageCaptchaGenerator removeImageCaptchaGenerator(String key) {
+ return imageCaptchaGeneratorMap.remove(key);
+ }
+
+ @Override
+ public ImageCaptchaInfo generateCaptchaImage(GenerateParam param) {
+ String type = param.getType();
+ if (ObjectUtils.isEmpty(type)){
+ param.setType(defaultCaptcha);
+ type = defaultCaptcha;
+ }
+ ImageCaptchaGenerator imageCaptchaGenerator = imageCaptchaGeneratorMap.get(type);
+ if (imageCaptchaGenerator == null) {
+ throw new IllegalArgumentException("生成验证码失败,错误的type类型:" + type);
+ }
+
+ return imageCaptchaGenerator.generateCaptchaImage(param);
+ }
+
+ @Override
+ public ImageCaptchaResourceManager getImageResourceManager() {
+ return imageCaptchaResourceManager;
+ }
+}
diff --git a/src/main/java/cloud/tianai/captcha/template/slider/generator/impl/StandardRotateCaptchaGenerator.java b/src/main/java/cloud/tianai/captcha/template/slider/generator/impl/StandardRotateImageCaptchaGenerator.java
similarity index 75%
rename from src/main/java/cloud/tianai/captcha/template/slider/generator/impl/StandardRotateCaptchaGenerator.java
rename to src/main/java/cloud/tianai/captcha/template/slider/generator/impl/StandardRotateImageCaptchaGenerator.java
index 12654b3..f784e57 100644
--- a/src/main/java/cloud/tianai/captcha/template/slider/generator/impl/StandardRotateCaptchaGenerator.java
+++ b/src/main/java/cloud/tianai/captcha/template/slider/generator/impl/StandardRotateImageCaptchaGenerator.java
@@ -7,8 +7,8 @@ import cloud.tianai.captcha.template.slider.generator.common.constant.SliderCapt
import cloud.tianai.captcha.template.slider.generator.common.model.dto.GenerateParam;
import cloud.tianai.captcha.template.slider.generator.common.model.dto.ImageCaptchaInfo;
import cloud.tianai.captcha.template.slider.generator.common.model.dto.RotateImageCaptchaInfo;
+import cloud.tianai.captcha.template.slider.resource.ImageCaptchaResourceManager;
import cloud.tianai.captcha.template.slider.resource.ResourceStore;
-import cloud.tianai.captcha.template.slider.resource.SliderCaptchaResourceManager;
import cloud.tianai.captcha.template.slider.resource.common.model.dto.Resource;
import cloud.tianai.captcha.template.slider.resource.impl.provider.ClassPathResourceProvider;
import lombok.SneakyThrows;
@@ -26,27 +26,27 @@ import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import static cloud.tianai.captcha.template.slider.common.util.CaptchaImageUtils.*;
-import static cloud.tianai.captcha.template.slider.generator.impl.StandardImageCaptchaGenerator.DEFAULT_SLIDER_IMAGE_RESOURCE_PATH;
-import static cloud.tianai.captcha.template.slider.generator.impl.StandardImageCaptchaGenerator.DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH;
+import static cloud.tianai.captcha.template.slider.generator.impl.StandardSliderImageCaptchaGenerator.DEFAULT_SLIDER_IMAGE_RESOURCE_PATH;
+import static cloud.tianai.captcha.template.slider.generator.impl.StandardSliderImageCaptchaGenerator.DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH;
/**
* @Author: 天爱有情
* @date 2022/4/22 16:43
* @Description 旋转图片验证码生成器
*/
-public class StandardRotateCaptchaGenerator extends AbstractImageCaptchaGenerator {
+public class StandardRotateImageCaptchaGenerator extends AbstractImageCaptchaGenerator {
- protected final SliderCaptchaResourceManager sliderCaptchaResourceManager;
+ protected final ImageCaptchaResourceManager imageCaptchaResourceManager;
- public StandardRotateCaptchaGenerator(SliderCaptchaResourceManager sliderCaptchaResourceManager, boolean initDefaultResource) {
- this.sliderCaptchaResourceManager = sliderCaptchaResourceManager;
+ public StandardRotateImageCaptchaGenerator(ImageCaptchaResourceManager imageCaptchaResourceManager, boolean initDefaultResource) {
+ this.imageCaptchaResourceManager = imageCaptchaResourceManager;
if (initDefaultResource) {
initDefaultResource();
}
}
public void initDefaultResource() {
- ResourceStore resourceStore = sliderCaptchaResourceManager.getResourceStore();
+ ResourceStore resourceStore = imageCaptchaResourceManager.getResourceStore();
// 添加一些系统的资源文件
resourceStore.addResource(CaptchaTypeConstant.ROTATE, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_RESOURCE_PATH.concat("/1.jpg")));
@@ -54,6 +54,7 @@ public class StandardRotateCaptchaGenerator extends AbstractImageCaptchaGenerato
Map template1 = new HashMap<>(4);
template1.put(SliderCaptchaConstant.TEMPLATE_ACTIVE_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/3/active.png")));
template1.put(SliderCaptchaConstant.TEMPLATE_FIXED_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/3/fixed.png")));
+ template1.put(SliderCaptchaConstant.TEMPLATE_MATRIX_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/3/matrix.png")));
resourceStore.addTemplate(CaptchaTypeConstant.ROTATE, template1);
}
@@ -61,14 +62,14 @@ public class StandardRotateCaptchaGenerator extends AbstractImageCaptchaGenerato
public ImageCaptchaInfo generateCaptchaImage(GenerateParam param) {
// 旋转验证码没有混淆
Boolean obfuscate = param.getObfuscate();
- Map templateImages = sliderCaptchaResourceManager.randomGetTemplate(param.getType());
+ Map templateImages = imageCaptchaResourceManager.randomGetTemplate(param.getType());
if (templateImages == null || templateImages.isEmpty()) {
return null;
}
Collection inputStreams = new LinkedList<>();
try {
- Resource resourceImage = sliderCaptchaResourceManager.randomGetResource(param.getType());
- InputStream resourceInputStream = sliderCaptchaResourceManager.getResourceInputStream(resourceImage);
+ Resource resourceImage = imageCaptchaResourceManager.randomGetResource(param.getType());
+ InputStream resourceInputStream = imageCaptchaResourceManager.getResourceInputStream(resourceImage);
inputStreams.add(resourceInputStream);
BufferedImage cutBackground = wrapFile2BufferedImage(resourceInputStream);
// 拷贝一份图片
@@ -81,6 +82,11 @@ public class StandardRotateCaptchaGenerator extends AbstractImageCaptchaGenerato
InputStream activeTemplateInput = getTemplateFile(templateImages, SliderCaptchaConstant.TEMPLATE_ACTIVE_IMAGE_NAME);
inputStreams.add(activeTemplateInput);
BufferedImage activeTemplate = wrapFile2BufferedImage(activeTemplateInput);
+
+ InputStream matrixTemplateInput = getTemplateFile(templateImages, SliderCaptchaConstant.TEMPLATE_MATRIX_IMAGE_NAME);
+ inputStreams.add(matrixTemplateInput);
+ BufferedImage matrixTemplate = wrapFile2BufferedImage(matrixTemplateInput);
+
// 算出居中的x和y
int x = targetBackground.getWidth() / 2 - fixedTemplate.getWidth() / 2;
int y = targetBackground.getHeight() / 2 - fixedTemplate.getHeight() / 2;
@@ -91,10 +97,10 @@ public class StandardRotateCaptchaGenerator extends AbstractImageCaptchaGenerato
// 随机旋转抠图部分
// 随机x, 转换为角度
int randomX = ThreadLocalRandom.current().nextInt(fixedTemplate.getWidth() + 10, targetBackground.getWidth() - 10);
- double degree = randomX / ((targetBackground.getWidth()) / 360d);
+ double degree = 360d - randomX / ((targetBackground.getWidth()) / 360d);
// int degree = ThreadLocalRandom.current().nextInt(10, 350);
- cutImage = rotateImage(cutImage, degree);
- return wrapRotateCaptchaInfo(degree, randomX, targetBackground, cutImage, param);
+ centerOverlayAndRotateImage(matrixTemplate, cutImage, degree);
+ return wrapRotateCaptchaInfo(degree, randomX, targetBackground, matrixTemplate, param);
} finally {
// 使用完后关闭流
for (InputStream inputStream : inputStreams) {
@@ -122,9 +128,19 @@ public class StandardRotateCaptchaGenerator extends AbstractImageCaptchaGenerato
);
}
+// @Override
+// public String transform(BufferedImage bufferedImage, String formatType) throws IOException {
+// FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Thinkpad\\Desktop\\aa" + formatType + "." + formatType);
+// ImageIO.write(bufferedImage, formatType, fileOutputStream);
+// fileOutputStream.close();
+//// return super.transform(bufferedImage, formatType);
+// return "";
+// }
+
+
@Override
- public SliderCaptchaResourceManager getSlideImageResourceManager() {
- return sliderCaptchaResourceManager;
+ public ImageCaptchaResourceManager getImageResourceManager() {
+ return imageCaptchaResourceManager;
}
public static void main(String[] args) throws IOException {
diff --git a/src/main/java/cloud/tianai/captcha/template/slider/generator/impl/StandardImageCaptchaGenerator.java b/src/main/java/cloud/tianai/captcha/template/slider/generator/impl/StandardSliderImageCaptchaGenerator.java
similarity index 88%
rename from src/main/java/cloud/tianai/captcha/template/slider/generator/impl/StandardImageCaptchaGenerator.java
rename to src/main/java/cloud/tianai/captcha/template/slider/generator/impl/StandardSliderImageCaptchaGenerator.java
index 547633e..1db1c2a 100644
--- a/src/main/java/cloud/tianai/captcha/template/slider/generator/impl/StandardImageCaptchaGenerator.java
+++ b/src/main/java/cloud/tianai/captcha/template/slider/generator/impl/StandardSliderImageCaptchaGenerator.java
@@ -6,8 +6,8 @@ import cloud.tianai.captcha.template.slider.generator.common.constant.SliderCapt
import cloud.tianai.captcha.template.slider.generator.common.model.dto.GenerateParam;
import cloud.tianai.captcha.template.slider.generator.common.model.dto.ImageCaptchaInfo;
import cloud.tianai.captcha.template.slider.generator.common.model.dto.SliderImageCaptchaInfo;
+import cloud.tianai.captcha.template.slider.resource.ImageCaptchaResourceManager;
import cloud.tianai.captcha.template.slider.resource.ResourceStore;
-import cloud.tianai.captcha.template.slider.resource.SliderCaptchaResourceManager;
import cloud.tianai.captcha.template.slider.resource.common.model.dto.Resource;
import cloud.tianai.captcha.template.slider.resource.impl.provider.ClassPathResourceProvider;
import lombok.SneakyThrows;
@@ -30,7 +30,7 @@ import static cloud.tianai.captcha.template.slider.common.util.CaptchaImageUtils
* @Description 滑块验证码模板
*/
@Slf4j
-public class StandardImageCaptchaGenerator extends AbstractImageCaptchaGenerator {
+public class StandardSliderImageCaptchaGenerator extends AbstractImageCaptchaGenerator {
/**
* 默认的resource资源文件路径.
@@ -41,12 +41,12 @@ public class StandardImageCaptchaGenerator extends AbstractImageCaptchaGenerator
*/
public static final String DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH = "META-INF/cut-image/template";
- protected final SliderCaptchaResourceManager sliderCaptchaResourceManager;
+ protected final ImageCaptchaResourceManager imageCaptchaResourceManager;
- public StandardImageCaptchaGenerator(SliderCaptchaResourceManager sliderCaptchaResourceManager,
- boolean initDefaultResource) {
- this.sliderCaptchaResourceManager = sliderCaptchaResourceManager;
+ public StandardSliderImageCaptchaGenerator(ImageCaptchaResourceManager imageCaptchaResourceManager,
+ boolean initDefaultResource) {
+ this.imageCaptchaResourceManager = imageCaptchaResourceManager;
if (initDefaultResource) {
initDefaultResource();
}
@@ -56,14 +56,14 @@ public class StandardImageCaptchaGenerator extends AbstractImageCaptchaGenerator
@Override
public ImageCaptchaInfo generateCaptchaImage(GenerateParam param) {
Boolean obfuscate = param.getObfuscate();
- Map templateImages = sliderCaptchaResourceManager.randomGetTemplate(param.getType());
+ Map templateImages = imageCaptchaResourceManager.randomGetTemplate(param.getType());
if (templateImages == null || templateImages.isEmpty()) {
return null;
}
Collection inputStreams = new LinkedList<>();
try {
- Resource resourceImage = sliderCaptchaResourceManager.randomGetResource(param.getType());
- InputStream resourceInputStream = sliderCaptchaResourceManager.getResourceInputStream(resourceImage);
+ Resource resourceImage = imageCaptchaResourceManager.randomGetResource(param.getType());
+ InputStream resourceInputStream = imageCaptchaResourceManager.getResourceInputStream(resourceImage);
inputStreams.add(resourceInputStream);
BufferedImage cutBackground = wrapFile2BufferedImage(resourceInputStream);
// 拷贝一份图片
@@ -139,8 +139,8 @@ public class StandardImageCaptchaGenerator extends AbstractImageCaptchaGenerator
}
@Override
- public SliderCaptchaResourceManager getSlideImageResourceManager() {
- return sliderCaptchaResourceManager;
+ public ImageCaptchaResourceManager getImageResourceManager() {
+ return imageCaptchaResourceManager;
}
protected int randomObfuscateX(int sliderX, int slWidth, int bgWidth) {
@@ -156,7 +156,7 @@ public class StandardImageCaptchaGenerator extends AbstractImageCaptchaGenerator
* 初始化默认资源
*/
public void initDefaultResource() {
- ResourceStore resourceStore = sliderCaptchaResourceManager.getResourceStore();
+ ResourceStore resourceStore = imageCaptchaResourceManager.getResourceStore();
// 添加一些系统的资源文件
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_RESOURCE_PATH.concat("/1.jpg")));
diff --git a/src/main/java/cloud/tianai/captcha/template/slider/resource/SliderCaptchaResourceManager.java b/src/main/java/cloud/tianai/captcha/template/slider/resource/ImageCaptchaResourceManager.java
similarity index 93%
rename from src/main/java/cloud/tianai/captcha/template/slider/resource/SliderCaptchaResourceManager.java
rename to src/main/java/cloud/tianai/captcha/template/slider/resource/ImageCaptchaResourceManager.java
index 2cc6fee..80e8fdf 100644
--- a/src/main/java/cloud/tianai/captcha/template/slider/resource/SliderCaptchaResourceManager.java
+++ b/src/main/java/cloud/tianai/captcha/template/slider/resource/ImageCaptchaResourceManager.java
@@ -9,9 +9,9 @@ import java.util.Map;
/**
* @Author: 天爱有情
* @date 2021/8/7 15:26
- * @Description 滑块验证码图片资源管理器
+ * @Description 验证码图片资源管理器
*/
-public interface SliderCaptchaResourceManager {
+public interface ImageCaptchaResourceManager {
/**
* 随机获取某个模板
diff --git a/src/main/java/cloud/tianai/captcha/template/slider/resource/impl/DefaultSliderCaptchaResourceManager.java b/src/main/java/cloud/tianai/captcha/template/slider/resource/impl/DefaultImageCaptchaResourceManager.java
similarity index 92%
rename from src/main/java/cloud/tianai/captcha/template/slider/resource/impl/DefaultSliderCaptchaResourceManager.java
rename to src/main/java/cloud/tianai/captcha/template/slider/resource/impl/DefaultImageCaptchaResourceManager.java
index 1e213a1..511bf1a 100644
--- a/src/main/java/cloud/tianai/captcha/template/slider/resource/impl/DefaultSliderCaptchaResourceManager.java
+++ b/src/main/java/cloud/tianai/captcha/template/slider/resource/impl/DefaultImageCaptchaResourceManager.java
@@ -1,8 +1,8 @@
package cloud.tianai.captcha.template.slider.resource.impl;
+import cloud.tianai.captcha.template.slider.resource.ImageCaptchaResourceManager;
import cloud.tianai.captcha.template.slider.resource.ResourceProvider;
import cloud.tianai.captcha.template.slider.resource.ResourceStore;
-import cloud.tianai.captcha.template.slider.resource.SliderCaptchaResourceManager;
import cloud.tianai.captcha.template.slider.resource.common.model.dto.Resource;
import cloud.tianai.captcha.template.slider.resource.impl.provider.ClassPathResourceProvider;
import cloud.tianai.captcha.template.slider.resource.impl.provider.FileResourceProvider;
@@ -19,18 +19,18 @@ import java.util.Map;
* @date 2021/8/7 15:35
* @Description 默认的滑块验证码资源管理
*/
-public class DefaultSliderCaptchaResourceManager implements SliderCaptchaResourceManager {
+public class DefaultImageCaptchaResourceManager implements ImageCaptchaResourceManager {
private ResourceStore resourceStore;
private List resourceProviderList = new ArrayList<>(8);
- public DefaultSliderCaptchaResourceManager() {
+ public DefaultImageCaptchaResourceManager() {
init();
}
- public DefaultSliderCaptchaResourceManager(ResourceStore resourceStore) {
+ public DefaultImageCaptchaResourceManager(ResourceStore resourceStore) {
this.resourceStore = resourceStore;
init();
}
diff --git a/src/main/resources/META-INF/cut-image/template/3/matrix.png b/src/main/resources/META-INF/cut-image/template/3/matrix.png
new file mode 100644
index 0000000..f4f18eb
Binary files /dev/null and b/src/main/resources/META-INF/cut-image/template/3/matrix.png differ
diff --git a/src/main/test/java/example/StandardRotateCaptchaGeneratorTest.java b/src/main/test/java/example/StandardRotateCaptchaGeneratorTest.java
index 0a67873..e882a8f 100644
--- a/src/main/test/java/example/StandardRotateCaptchaGeneratorTest.java
+++ b/src/main/test/java/example/StandardRotateCaptchaGeneratorTest.java
@@ -1,18 +1,13 @@
package example;
import cloud.tianai.captcha.template.slider.generator.common.constant.CaptchaTypeConstant;
-import cloud.tianai.captcha.template.slider.generator.common.constant.SliderCaptchaConstant;
import cloud.tianai.captcha.template.slider.generator.common.model.dto.ImageCaptchaInfo;
import cloud.tianai.captcha.template.slider.generator.common.model.dto.RotateImageCaptchaInfo;
-import cloud.tianai.captcha.template.slider.generator.impl.StandardRotateCaptchaGenerator;
+import cloud.tianai.captcha.template.slider.generator.impl.StandardRotateImageCaptchaGenerator;
+import cloud.tianai.captcha.template.slider.resource.ImageCaptchaResourceManager;
import cloud.tianai.captcha.template.slider.resource.ResourceStore;
-import cloud.tianai.captcha.template.slider.resource.SliderCaptchaResourceManager;
-import cloud.tianai.captcha.template.slider.resource.common.model.dto.Resource;
+import cloud.tianai.captcha.template.slider.resource.impl.DefaultImageCaptchaResourceManager;
import cloud.tianai.captcha.template.slider.resource.impl.DefaultResourceStore;
-import cloud.tianai.captcha.template.slider.resource.impl.DefaultSliderCaptchaResourceManager;
-
-import java.util.HashMap;
-import java.util.Map;
public class StandardRotateCaptchaGeneratorTest {
@@ -25,10 +20,10 @@ public class StandardRotateCaptchaGeneratorTest {
// resourceStore.addTemplate(CaptchaTypeConstant.ROTATE, template);
// resourceStore.addResource(CaptchaTypeConstant.ROTATE, new Resource("file", "E:\\projects\\tianai-captcha\\src\\main\\resources\\META-INF\\cut-image\\resource\\1.jpg"));
- SliderCaptchaResourceManager sliderCaptchaResourceManager = new DefaultSliderCaptchaResourceManager(resourceStore);
+ ImageCaptchaResourceManager imageCaptchaResourceManager = new DefaultImageCaptchaResourceManager(resourceStore);
- StandardRotateCaptchaGenerator standardRotateCaptchaGenerator = new StandardRotateCaptchaGenerator(sliderCaptchaResourceManager, true);
- ImageCaptchaInfo imageCaptchaInfo = standardRotateCaptchaGenerator.generateCaptchaImage(CaptchaTypeConstant.ROTATE);
+ StandardRotateImageCaptchaGenerator standardRotateImageCaptchaGenerator = new StandardRotateImageCaptchaGenerator(imageCaptchaResourceManager, true);
+ ImageCaptchaInfo imageCaptchaInfo = standardRotateImageCaptchaGenerator.generateCaptchaImage(CaptchaTypeConstant.ROTATE);
System.out.println("backgroundImage:" + imageCaptchaInfo.getBackgroundImage());
System.out.println("sliderImage:" + imageCaptchaInfo.getSliderImage());
System.out.println(((RotateImageCaptchaInfo)imageCaptchaInfo).getDegree());