优化滑动还原验证码生成效率

修复一些小bug
This commit is contained in:
天爱有情
2023-08-30 08:50:00 +08:00
parent 866db7c43b
commit b235fbe585
3 changed files with 97 additions and 23 deletions
@@ -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);
}
} }