From b235fbe585f0b8ab5c2e87c43623f9cbf4c88625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E7=88=B1=E6=9C=89=E6=83=85?= Date: Wed, 30 Aug 2023 08:50:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=BB=91=E5=8A=A8=E8=BF=98?= =?UTF-8?q?=E5=8E=9F=E9=AA=8C=E8=AF=81=E7=A0=81=E7=94=9F=E6=88=90=E6=95=88?= =?UTF-8?q?=E7=8E=87=20=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=BA=9B=E5=B0=8Fbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/model/dto/GenerateParam.java | 43 ++++++++++-- .../common/util/CaptchaImageUtils.java | 67 ++++++++++++++----- .../common/model/dto/ResourceMap.java | 10 +++ 3 files changed, 97 insertions(+), 23 deletions(-) diff --git a/src/main/java/cloud/tianai/captcha/generator/common/model/dto/GenerateParam.java b/src/main/java/cloud/tianai/captcha/generator/common/model/dto/GenerateParam.java index 76eb763..d96d3ea 100644 --- a/src/main/java/cloud/tianai/captcha/generator/common/model/dto/GenerateParam.java +++ b/src/main/java/cloud/tianai/captcha/generator/common/model/dto/GenerateParam.java @@ -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 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 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); + } } diff --git a/src/main/java/cloud/tianai/captcha/generator/common/util/CaptchaImageUtils.java b/src/main/java/cloud/tianai/captcha/generator/common/util/CaptchaImageUtils.java index 146e993..66b19f9 100644 --- a/src/main/java/cloud/tianai/captcha/generator/common/util/CaptchaImageUtils.java +++ b/src/main/java/cloud/tianai/captcha/generator/common/util/CaptchaImageUtils.java @@ -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 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; } diff --git a/src/main/java/cloud/tianai/captcha/resource/common/model/dto/ResourceMap.java b/src/main/java/cloud/tianai/captcha/resource/common/model/dto/ResourceMap.java index 31a74ff..6fa8aaa 100644 --- a/src/main/java/cloud/tianai/captcha/resource/common/model/dto/ResourceMap.java +++ b/src/main/java/cloud/tianai/captcha/resource/common/model/dto/ResourceMap.java @@ -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 values() { + return getResourceMapOfCreate().values(); + } + + public void forEach(BiConsumer action) { + getResourceMapOfCreate().forEach(action); + } }