mirror of
https://github.com/dromara/tianai-captcha.git
synced 2026-05-07 14:13:05 +08:00
更改验证器类名
This commit is contained in:
+98
-17
@@ -175,23 +175,6 @@ public class CaptchaImageUtils {
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * 旋转图片
|
||||
// *
|
||||
// * @param bufferedImage 图片
|
||||
// * @param degree 旋转xx度
|
||||
// */
|
||||
// public static void rotateImage(BufferedImage bufferedImage, int degree) {
|
||||
// // 创建Graphics2D对象,用在底图对象上绘图
|
||||
// Graphics2D g2d = bufferedImage.createGraphics();
|
||||
// // 绘制
|
||||
// g2d.rotate(Math.toRadians(degree), bufferedImage.getWidth() / 2, bufferedImage.getHeight()/2);
|
||||
// g2d.drawImage(bufferedImage, 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), null);
|
||||
// // 释放图形上下文使用的系统资源
|
||||
// g2d.dispose();
|
||||
// }
|
||||
|
||||
public static BufferedImage rotateImage(final BufferedImage bufferedimage,
|
||||
final double degree) {
|
||||
// 得到图片宽度。
|
||||
@@ -225,4 +208,102 @@ public class CaptchaImageUtils {
|
||||
overlayImage(baseBufferedImage, coverBufferedImage, bw / 2 - cw / 2, bh / 2 - ch / 2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过x和y轴截取图片
|
||||
*
|
||||
* @param x x
|
||||
* @param y y
|
||||
* @param width 宽度
|
||||
* @param height 高度
|
||||
* @param img 截取的图片
|
||||
* @return BufferedImage
|
||||
*/
|
||||
public static BufferedImage subImage(int x, int y, int width, int height, BufferedImage img) {
|
||||
int[] simgRgb = new int[width * height];
|
||||
img.getRGB(x, y, width, height, simgRgb, 0, width);
|
||||
// 得到图片透明度。
|
||||
int type = img.getColorModel().getTransparency();
|
||||
BufferedImage newImage = new BufferedImage(width, height, type);
|
||||
newImage.setRGB(0, 0, width, height, simgRgb, 0, width);
|
||||
return newImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分隔图片
|
||||
*
|
||||
* @param pos 分隔点
|
||||
* @param direction true为水平方向, false为垂直方向
|
||||
* @param img 待分割的图片
|
||||
* @return BufferedImage[]
|
||||
*/
|
||||
public static BufferedImage[] splitImage(int pos, boolean direction, BufferedImage img) {
|
||||
int startImageWidth;
|
||||
int startImageHeight;
|
||||
int endImageWidth;
|
||||
int endImageHeight;
|
||||
int endScanX;
|
||||
int endScanY;
|
||||
if (direction) {
|
||||
startImageHeight = img.getHeight() - pos;
|
||||
startImageWidth = img.getWidth();
|
||||
endImageWidth = img.getWidth();
|
||||
endImageHeight = pos;
|
||||
endScanX = 0;
|
||||
endScanY = startImageHeight;
|
||||
} else {
|
||||
startImageWidth = pos;
|
||||
startImageHeight = img.getHeight();
|
||||
endImageWidth = img.getWidth() - startImageWidth;
|
||||
endImageHeight = img.getHeight();
|
||||
endScanX = pos;
|
||||
endScanY = 0;
|
||||
}
|
||||
|
||||
// start
|
||||
int[] rgbArr = new int[startImageWidth * startImageHeight];
|
||||
img.getRGB(0, 0, startImageWidth, startImageHeight, rgbArr, 0, startImageWidth);
|
||||
int type = img.getColorModel().getTransparency();
|
||||
BufferedImage startImg = new BufferedImage(startImageWidth, startImageHeight, type);
|
||||
startImg.setRGB(0, 0, startImageWidth, startImageHeight, rgbArr, 0, startImageWidth);
|
||||
// end
|
||||
rgbArr = new int[endImageWidth * endImageHeight];
|
||||
img.getRGB(endScanX, endScanY, endImageWidth, endImageHeight, rgbArr, 0, endImageWidth);
|
||||
BufferedImage endImg = new BufferedImage(endImageWidth, endImageHeight, type);
|
||||
endImg.setRGB(0, 0, endImageWidth, endImageHeight, rgbArr, 0, endImageWidth);
|
||||
|
||||
BufferedImage[] splitImageArr = new BufferedImage[2];
|
||||
splitImageArr[0] = startImg;
|
||||
splitImageArr[1] = endImg;
|
||||
return splitImageArr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 拼接图片
|
||||
*
|
||||
* @param direction rue为水平方向, false为垂直方向
|
||||
* @param width 拼接后图片宽度
|
||||
* @param height 拼接后图片高度
|
||||
* @param imgArr 拼接的图片数组
|
||||
* @return BufferedImage
|
||||
*/
|
||||
public static BufferedImage concatImage(boolean direction, int width, int height, BufferedImage... imgArr) {
|
||||
int pos = 0;
|
||||
BufferedImage newImage = new BufferedImage(width, height, imgArr[0].getColorModel().getTransparency());
|
||||
for (BufferedImage img : imgArr) {
|
||||
int[] rgbArr = new int[width * height];
|
||||
img.getRGB(0, 0, img.getWidth(), img.getHeight(), rgbArr, 0, img.getWidth());
|
||||
if (direction) {
|
||||
newImage.setRGB(pos, 0, img.getWidth(), img.getHeight(), rgbArr, 0, img.getWidth());
|
||||
pos += img.getWidth();
|
||||
// 水平方向
|
||||
} else {
|
||||
// 垂直方向
|
||||
newImage.setRGB(0, pos, img.getWidth(), img.getHeight(), rgbArr, 0, img.getWidth());
|
||||
pos += img.getHeight();
|
||||
}
|
||||
}
|
||||
return newImage;
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -11,4 +11,6 @@ public interface CaptchaTypeConstant {
|
||||
String SLIDER = "SLIDER";
|
||||
/** 旋转. */
|
||||
String ROTATE = "ROTATE";
|
||||
/** 拼接.*/
|
||||
String CONCAT = "CONCAT";
|
||||
}
|
||||
|
||||
+4
@@ -31,8 +31,12 @@ public class MultiImageCaptchaGenerator extends AbstractImageCaptchaGenerator {
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
// 滑块验证码
|
||||
addImageCaptchaGenerator(CaptchaTypeConstant.SLIDER, new StandardSliderImageCaptchaGenerator(imageCaptchaResourceManager, initDefaultResource));
|
||||
// 旋转验证码
|
||||
addImageCaptchaGenerator(CaptchaTypeConstant.ROTATE, new StandardRotateImageCaptchaGenerator(imageCaptchaResourceManager, initDefaultResource));
|
||||
// 拼接验证码
|
||||
addImageCaptchaGenerator(CaptchaTypeConstant.CONCAT, new StandardConcatImageCaptchaGenerator(imageCaptchaResourceManager, initDefaultResource));
|
||||
}
|
||||
|
||||
public void addImageCaptchaGenerator(String key, ImageCaptchaGenerator captchaGenerator) {
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package cloud.tianai.captcha.template.slider.generator.impl;
|
||||
|
||||
import cloud.tianai.captcha.template.slider.generator.AbstractImageCaptchaGenerator;
|
||||
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 cloud.tianai.captcha.template.slider.resource.ResourceStore;
|
||||
import cloud.tianai.captcha.template.slider.resource.common.model.dto.Resource;
|
||||
import cloud.tianai.captcha.template.slider.resource.impl.provider.ClassPathResourceProvider;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import static cloud.tianai.captcha.template.slider.common.util.CaptchaImageUtils.*;
|
||||
import static cloud.tianai.captcha.template.slider.generator.impl.StandardSliderImageCaptchaGenerator.DEFAULT_SLIDER_IMAGE_RESOURCE_PATH;
|
||||
|
||||
/**
|
||||
* @Author: 天爱有情
|
||||
* @date 2022/4/25 15:44
|
||||
* @Description 图片拼接滑动验证码生成器
|
||||
*/
|
||||
public class StandardConcatImageCaptchaGenerator extends AbstractImageCaptchaGenerator {
|
||||
|
||||
protected final ImageCaptchaResourceManager imageCaptchaResourceManager;
|
||||
|
||||
public StandardConcatImageCaptchaGenerator(ImageCaptchaResourceManager imageCaptchaResourceManager, boolean initDefaultResource) {
|
||||
this.imageCaptchaResourceManager = imageCaptchaResourceManager;
|
||||
if (initDefaultResource) {
|
||||
initDefaultResource();
|
||||
}
|
||||
}
|
||||
|
||||
public void initDefaultResource() {
|
||||
ResourceStore resourceStore = imageCaptchaResourceManager.getResourceStore();
|
||||
// 添加一些系统的资源文件
|
||||
resourceStore.addResource(CaptchaTypeConstant.CONCAT, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_RESOURCE_PATH.concat("/1.jpg")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageCaptchaInfo generateCaptchaImage(GenerateParam param) {
|
||||
// 拼接验证码不需要模板 只需要背景图
|
||||
Collection<InputStream> inputStreams = new LinkedList<>();
|
||||
try {
|
||||
Resource resourceImage = imageCaptchaResourceManager.randomGetResource(param.getType());
|
||||
InputStream resourceInputStream = imageCaptchaResourceManager.getResourceInputStream(resourceImage);
|
||||
inputStreams.add(resourceInputStream);
|
||||
BufferedImage bgImage = wrapFile2BufferedImage(resourceInputStream);
|
||||
int spacing = bgImage.getHeight() / 4;
|
||||
BufferedImage[] bgImageSplit = splitImage(ThreadLocalRandom.current().nextInt(spacing, bgImage.getHeight() - spacing), true, bgImage);
|
||||
|
||||
spacing = bgImage.getWidth() / 8;
|
||||
int randomX = ThreadLocalRandom.current().nextInt(spacing, bgImage.getWidth() - spacing);
|
||||
BufferedImage[] bgImageTopSplit = splitImage(randomX, false, bgImageSplit[0]);
|
||||
|
||||
BufferedImage sliderImage = concatImage(true,
|
||||
bgImageTopSplit[0].getWidth()
|
||||
+ bgImageTopSplit[1].getWidth()
|
||||
+ bgImageSplit[0].getWidth(), bgImageTopSplit[1].getHeight(), bgImageSplit[0], bgImageTopSplit[0]);
|
||||
return wrapConcatCaptchaInfo(randomX, bgImageSplit[1], sliderImage, param);
|
||||
} finally {
|
||||
// 使用完后关闭流
|
||||
for (InputStream inputStream : inputStreams) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private ImageCaptchaInfo wrapConcatCaptchaInfo(int randomX, BufferedImage bgImage, BufferedImage sliderImage, GenerateParam param) {
|
||||
String backGroundImageBase64 = transform(bgImage, param.getBackgroundFormatName());
|
||||
String sliderImageBase64 = transform(sliderImage, param.getSliderFormatName());
|
||||
return ImageCaptchaInfo.of(backGroundImageBase64, sliderImageBase64, bgImage.getWidth(), bgImage.getHeight(), sliderImage.getWidth(), sliderImage.getHeight(), randomX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageCaptchaResourceManager getImageResourceManager() {
|
||||
return imageCaptchaResourceManager;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user