mirror of
https://github.com/dromara/tianai-captcha.git
synced 2026-05-07 06:04:34 +08:00
优化滑动还原验证码生成效率
修复一些小bug
This commit is contained in:
@@ -1,9 +1,11 @@
|
|||||||
package cloud.tianai.captcha.generator.common.model.dto;
|
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.*;
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: 天爱有情
|
* @Author: 天爱有情
|
||||||
* @date 2022/2/11 9:44
|
* @date 2022/2/11 9:44
|
||||||
@@ -15,6 +17,8 @@ import lombok.*;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
public class GenerateParam {
|
public class GenerateParam {
|
||||||
|
|
||||||
|
|
||||||
/** 背景格式化类型. */
|
/** 背景格式化类型. */
|
||||||
private String backgroundFormatName = "jpeg";
|
private String backgroundFormatName = "jpeg";
|
||||||
/** 模板图片格式化类型. */
|
/** 模板图片格式化类型. */
|
||||||
@@ -24,9 +28,38 @@ public class GenerateParam {
|
|||||||
/** 类型. */
|
/** 类型. */
|
||||||
private String type = CaptchaTypeConstant.SLIDER;
|
private String type = CaptchaTypeConstant.SLIDER;
|
||||||
/** 背景图片标签, 用户二级过滤背景图片,或指定某背景图片. */
|
/** 背景图片标签, 用户二级过滤背景图片,或指定某背景图片. */
|
||||||
private String backgroundImageTag = CommonConstant.DEFAULT_TAG;
|
private String backgroundImageTag;
|
||||||
/** 滑动图片标签,用户二级过滤模板图片,或指定某模板图片.. */
|
/** 滑动图片标签,用户二级过滤模板图片,或指定某模板图片.. */
|
||||||
private String templateImageTag = CommonConstant.DEFAULT_TAG;
|
private String templateImageTag;
|
||||||
/** 扩展参数. */
|
/** 扩展参数. */
|
||||||
private Object param;
|
private Map<String, Object> param = new HashMap<>(4);
|
||||||
|
|
||||||
|
public void addParam(String key, Object value) {
|
||||||
|
doGetOrCreateParam().put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getParam(String key) {
|
||||||
|
return param == null ? null : param.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Object> doGetOrCreateParam() {
|
||||||
|
if (param == null) {
|
||||||
|
param = new HashMap<>(4);
|
||||||
|
}
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object removeParam(String key) {
|
||||||
|
if (param == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return param.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getOrDefault(String key, Object defaultValue) {
|
||||||
|
if (param == null) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
return param.getOrDefault(key, defaultValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,23 @@
|
|||||||
package cloud.tianai.captcha.generator.common.util;
|
package cloud.tianai.captcha.generator.common.util;
|
||||||
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.geom.Area;
|
import java.awt.geom.Area;
|
||||||
import java.awt.geom.CubicCurve2D;
|
import java.awt.geom.CubicCurve2D;
|
||||||
import java.awt.geom.QuadCurve2D;
|
import java.awt.geom.QuadCurve2D;
|
||||||
import java.awt.image.*;
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.image.PixelGrabber;
|
||||||
|
import java.awt.image.RenderedImage;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: 天爱有情
|
* @Author: 天爱有情
|
||||||
@@ -69,6 +75,25 @@ public class CaptchaImageUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static int getMaxPix(BufferedImage image, int x, int y, int width, int height) {
|
||||||
|
int[] rgbArr = new int[width * height];
|
||||||
|
image.getRGB(x, y, width, height, rgbArr, 0, width);
|
||||||
|
Map<Integer, Integer> map = new HashMap<>();
|
||||||
|
for (int rgb : rgbArr) {
|
||||||
|
Integer count = map.getOrDefault(rgb, 0);
|
||||||
|
map.put(rgb, count + 1);
|
||||||
|
}
|
||||||
|
AtomicInteger maxRgb = new AtomicInteger();
|
||||||
|
AtomicInteger maxRgbCount = new AtomicInteger();
|
||||||
|
map.forEach((r, c) -> {
|
||||||
|
if (c > maxRgbCount.get()) {
|
||||||
|
maxRgb.set(r);
|
||||||
|
maxRgbCount.set(c);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return maxRgb.get();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将Image图像中的透明/不透明部分转换为Shape图形
|
* 将Image图像中的透明/不透明部分转换为Shape图形
|
||||||
*
|
*
|
||||||
@@ -196,6 +221,22 @@ public class CaptchaImageUtils {
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void replaceColorByOpaque(BufferedImage oriImage, int replaceRgb) {
|
||||||
|
int bh = oriImage.getHeight();
|
||||||
|
int bw = oriImage.getWidth();
|
||||||
|
// 透明色
|
||||||
|
for (int y = 0; y < bh; y++) {
|
||||||
|
for (int x = 0; x < bw; x++) {
|
||||||
|
int rgb = oriImage.getRGB(x, y);
|
||||||
|
int alpha = (rgb >> 24) & 0xff;
|
||||||
|
// 透明度大于100才处理,过滤一下边缘过于透明的像素点
|
||||||
|
if (alpha > 100) {
|
||||||
|
oriImage.setRGB(x, y, replaceRgb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 旋转图片
|
* 旋转图片
|
||||||
*
|
*
|
||||||
@@ -288,17 +329,8 @@ public class CaptchaImageUtils {
|
|||||||
endScanY = 0;
|
endScanY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start
|
BufferedImage startImg = img.getSubimage(0, 0, startImageWidth, startImageHeight);
|
||||||
int[] rgbArr = new int[startImageWidth * startImageHeight];
|
BufferedImage endImg = img.getSubimage(endScanX, endScanY, endImageWidth, endImageHeight);
|
||||||
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];
|
BufferedImage[] splitImageArr = new BufferedImage[2];
|
||||||
splitImageArr[0] = startImg;
|
splitImageArr[0] = startImg;
|
||||||
@@ -306,7 +338,6 @@ public class CaptchaImageUtils {
|
|||||||
return splitImageArr;
|
return splitImageArr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拼接图片
|
* 拼接图片
|
||||||
*
|
*
|
||||||
@@ -319,19 +350,19 @@ public class CaptchaImageUtils {
|
|||||||
public static BufferedImage concatImage(boolean direction, int width, int height, BufferedImage... imgArr) {
|
public static BufferedImage concatImage(boolean direction, int width, int height, BufferedImage... imgArr) {
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
BufferedImage newImage = new BufferedImage(width, height, imgArr[0].getColorModel().getTransparency());
|
BufferedImage newImage = new BufferedImage(width, height, imgArr[0].getColorModel().getTransparency());
|
||||||
|
Graphics2D graphics = newImage.createGraphics();
|
||||||
for (BufferedImage img : imgArr) {
|
for (BufferedImage img : imgArr) {
|
||||||
int[] rgbArr = new int[width * height];
|
|
||||||
img.getRGB(0, 0, img.getWidth(), img.getHeight(), rgbArr, 0, img.getWidth());
|
|
||||||
if (direction) {
|
if (direction) {
|
||||||
newImage.setRGB(pos, 0, img.getWidth(), img.getHeight(), rgbArr, 0, img.getWidth());
|
|
||||||
pos += img.getWidth();
|
|
||||||
// 水平方向
|
// 水平方向
|
||||||
|
graphics.drawImage(img, pos, 0, img.getWidth(), img.getHeight(),null);
|
||||||
|
pos += img.getWidth();
|
||||||
} else {
|
} else {
|
||||||
// 垂直方向
|
// 垂直方向
|
||||||
newImage.setRGB(0, pos, img.getWidth(), img.getHeight(), rgbArr, 0, img.getWidth());
|
graphics.drawImage(img, 0, pos, img.getWidth(), img.getHeight(),null);
|
||||||
pos += img.getHeight();
|
pos += img.getHeight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
graphics.dispose();
|
||||||
return newImage;
|
return newImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ package cloud.tianai.captcha.resource.common.model.dto;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: 天爱有情
|
* @Author: 天爱有情
|
||||||
@@ -51,8 +53,16 @@ public class ResourceMap {
|
|||||||
public Resource get(Object key) {
|
public Resource get(Object key) {
|
||||||
return getResourceMapOfCreate().get(key);
|
return getResourceMapOfCreate().get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Resource remove(Object key) {
|
public Resource remove(Object key) {
|
||||||
return getResourceMapOfCreate().remove(key);
|
return getResourceMapOfCreate().remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collection<Resource> values() {
|
||||||
|
return getResourceMapOfCreate().values();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void forEach(BiConsumer<String, Resource> action) {
|
||||||
|
getResourceMapOfCreate().forEach(action);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user