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;
|
||||
|
||||
import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
|
||||
import cloud.tianai.captcha.common.constant.CommonConstant;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author: 天爱有情
|
||||
* @date 2022/2/11 9:44
|
||||
@@ -15,6 +17,8 @@ import lombok.*;
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
public class GenerateParam {
|
||||
|
||||
|
||||
/** 背景格式化类型. */
|
||||
private String backgroundFormatName = "jpeg";
|
||||
/** 模板图片格式化类型. */
|
||||
@@ -24,9 +28,38 @@ public class GenerateParam {
|
||||
/** 类型. */
|
||||
private String type = CaptchaTypeConstant.SLIDER;
|
||||
/** 背景图片标签, 用户二级过滤背景图片,或指定某背景图片. */
|
||||
private String backgroundImageTag = CommonConstant.DEFAULT_TAG;
|
||||
private String backgroundImageTag;
|
||||
/** 滑动图片标签,用户二级过滤模板图片,或指定某模板图片.. */
|
||||
private String templateImageTag = CommonConstant.DEFAULT_TAG;
|
||||
/** 扩展参数.*/
|
||||
private Object param;
|
||||
private String templateImageTag;
|
||||
/** 扩展参数. */
|
||||
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;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.CubicCurve2D;
|
||||
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.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* @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图形
|
||||
*
|
||||
@@ -196,6 +221,22 @@ public class CaptchaImageUtils {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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 startImg = img.getSubimage(0, 0, startImageWidth, startImageHeight);
|
||||
BufferedImage endImg = img.getSubimage(endScanX, endScanY, endImageWidth, endImageHeight);
|
||||
|
||||
BufferedImage[] splitImageArr = new BufferedImage[2];
|
||||
splitImageArr[0] = startImg;
|
||||
@@ -306,7 +338,6 @@ public class CaptchaImageUtils {
|
||||
return splitImageArr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 拼接图片
|
||||
*
|
||||
@@ -319,19 +350,19 @@ public class CaptchaImageUtils {
|
||||
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());
|
||||
Graphics2D graphics = newImage.createGraphics();
|
||||
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();
|
||||
// 水平方向
|
||||
graphics.drawImage(img, pos, 0, img.getWidth(), img.getHeight(),null);
|
||||
pos += img.getWidth();
|
||||
} 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();
|
||||
}
|
||||
}
|
||||
graphics.dispose();
|
||||
return newImage;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,10 @@ package cloud.tianai.captcha.resource.common.model.dto;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* @Author: 天爱有情
|
||||
@@ -51,8 +53,16 @@ public class ResourceMap {
|
||||
public Resource get(Object key) {
|
||||
return getResourceMapOfCreate().get(key);
|
||||
}
|
||||
|
||||
public Resource remove(Object 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