From c85e79d69887dedc81ef6d3669134293fe60e91e Mon Sep 17 00:00:00 2001 From: chenzecheng <陈泽成@chenzecheng> Date: Thu, 8 Aug 2024 14:46:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=9B=BE=E5=BD=A2=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E7=A0=81=E6=96=87=E5=AD=97=E9=A2=9C=E8=89=B2=E4=B8=8E?= =?UTF-8?q?=E8=83=8C=E6=99=AF=E9=A2=9C=E8=89=B2=E8=89=B2=E5=B7=AE=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/hutool/captcha/CaptchaUtilTest.java | 75 +++++++++++++++++++ .../java/cn/hutool/core/img/ColorUtil.java | 33 ++++++++ .../java/cn/hutool/core/img/GraphicsUtil.java | 37 +++++++-- .../main/java/cn/hutool/core/img/ImgUtil.java | 12 +++ 4 files changed, 150 insertions(+), 7 deletions(-) diff --git a/hutool-captcha/src/test/java/cn/hutool/captcha/CaptchaUtilTest.java b/hutool-captcha/src/test/java/cn/hutool/captcha/CaptchaUtilTest.java index d57cc393d..f3c03eab5 100755 --- a/hutool-captcha/src/test/java/cn/hutool/captcha/CaptchaUtilTest.java +++ b/hutool-captcha/src/test/java/cn/hutool/captcha/CaptchaUtilTest.java @@ -1,8 +1,18 @@ package cn.hutool.captcha; +import cn.hutool.captcha.generator.CodeGenerator; +import cn.hutool.captcha.generator.MathGenerator; +import cn.hutool.core.img.GraphicsUtil; +import cn.hutool.core.img.ImgUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.RandomUtil; import org.junit.Ignore; import org.junit.Test; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.concurrent.ThreadLocalRandom; + public class CaptchaUtilTest { @Test @@ -12,4 +22,69 @@ public class CaptchaUtilTest { CaptchaUtil.createShearCaptcha(320, 240); } } + + @Test + @Ignore + public void drawStringColourfulTest() { + for(int i = 0; i < 10; i++) { + AbstractCaptcha lineCaptcha = new TestLineCaptcha(200, 100, 5, 10); + lineCaptcha.write("d:/captcha/line"+i+".png"); + } + } + + static class TestLineCaptcha extends AbstractCaptcha{ + + public TestLineCaptcha(int width, int height, int codeCount, int interfereCount) { + super(width, height, codeCount, interfereCount); + } + + @Override + protected Image createImage(String code) { + // 图像buffer + final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + final Graphics2D g = GraphicsUtil.createGraphics(image, ObjectUtil.defaultIfNull(this.background, Color.WHITE)); + + // 干扰线 + drawInterfere(g); + + // 字符串 + drawString(g, code); + + return image; + } + + // ----------------------------------------------------------------------------------------------------- Private method start + /** + * 绘制字符串 + * + * @param g {@link Graphics}画笔 + * @param code 验证码 + */ + private void drawString(Graphics2D g, String code) { + // 指定透明度 + if (null != this.textAlpha) { + g.setComposite(this.textAlpha); + } + GraphicsUtil.drawStringColourful(g, code, this.font, this.width, this.height,Color.WHITE,200); + } + + /** + * 绘制干扰线 + * + * @param g {@link Graphics2D}画笔 + */ + private void drawInterfere(Graphics2D g) { + final ThreadLocalRandom random = RandomUtil.getRandom(); + // 干扰线 + for (int i = 0; i < this.interfereCount; i++) { + int xs = random.nextInt(width); + int ys = random.nextInt(height); + int xe = xs + random.nextInt(width / 3); + int ye = ys + random.nextInt(height / 3); + g.setColor(ImgUtil.randomColor(random)); + g.drawLine(xs, ys, xe, ye); + } + } + // ----------------------------------------------------------------------------------------------------- Private method start + } } diff --git a/hutool-core/src/main/java/cn/hutool/core/img/ColorUtil.java b/hutool-core/src/main/java/cn/hutool/core/img/ColorUtil.java index f67acc40f..969cf1d05 100644 --- a/hutool-core/src/main/java/cn/hutool/core/img/ColorUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/img/ColorUtil.java @@ -179,6 +179,39 @@ public class ColorUtil { return randomColor(null); } + /** + * 生成随机颜色,与指定颜色有一定的区分度 + * + * @param compareColor 比较颜色 + * @param minDistance 最小色差,按三维坐标计算的距离值 + * @return 随机颜色 + * @since 5.8.30 + */ + public static Color randomColor(Color compareColor,int minDistance) { + Color color = randomColor(null); + while (computeColorDistance(compareColor,color) < minDistance) { + color = randomColor(null); + } + return color; + } + + /** + * 计算两个颜色之间的色差,按三维坐标距离计算 + * + * @param color1 颜色1 + * @param color2 颜色2 + * @return 色差,按三维坐标距离值 + * @since 5.8.30 + */ + public static int computeColorDistance(Color color1, Color color2) { + if (null == color1 || null == color2) { + return 0; + } + return (int) Math.sqrt(Math.pow(color1.getRed() - color2.getRed(), 2) + + Math.pow(color1.getGreen() - color2.getGreen(), 2) + + Math.pow(color1.getBlue() - color2.getBlue(), 2)); + } + /** * 生成随机颜色 * diff --git a/hutool-core/src/main/java/cn/hutool/core/img/GraphicsUtil.java b/hutool-core/src/main/java/cn/hutool/core/img/GraphicsUtil.java index 79cf288d2..d67cb4b4e 100755 --- a/hutool-core/src/main/java/cn/hutool/core/img/GraphicsUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/img/GraphicsUtil.java @@ -81,7 +81,24 @@ public class GraphicsUtil { * @since 4.5.10 */ public static Graphics drawStringColourful(Graphics g, String str, Font font, int width, int height) { - return drawString(g, str, font, null, width, height); + return drawString(g, str, font, null, width, height, null, 0); + } + + /** + * 绘制字符串,使用随机颜色,默认抗锯齿 + * + * @param g {@link Graphics}画笔 + * @param str 字符串 + * @param font 字体 + * @param width 字符串总宽度 + * @param height 字符串背景高度 + * @param compareColor 用于比对的颜色 + * @param minColorDistance 随机生成的颜色与对比颜色的最小色差,小于此值则重新生成颜色 + * @return 画笔对象 + * @since 4.5.10 + */ + public static Graphics drawStringColourful(Graphics g, String str, Font font, int width, int height, Color compareColor, int minColorDistance) { + return drawString(g, str, font, null, width, height, compareColor, minColorDistance); } /** @@ -93,10 +110,12 @@ public class GraphicsUtil { * @param color 字体颜色,{@code null} 表示使用随机颜色(每个字符单独随机) * @param width 字符串背景的宽度 * @param height 字符串背景的高度 + * @param compareColor 用于比对的颜色 + * @param minColorDistance 随机生成的颜色与对比颜色的最小色差,小于此值则重新生成颜色 * @return 画笔对象 * @since 4.5.10 */ - public static Graphics drawString(Graphics g, String str, Font font, Color color, int width, int height) { + public static Graphics drawString(Graphics g, String str, Font font, Color color, int width, int height, Color compareColor, int minColorDistance) { // 抗锯齿 if (g instanceof Graphics2D) { ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); @@ -115,7 +134,11 @@ public class GraphicsUtil { for (int i = 0; i < len; i++) { if (null == color) { // 产生随机的颜色值,让输出的每个字符的颜色值都将不同。 - g.setColor(ImgUtil.randomColor()); + if (null != compareColor && minColorDistance > 0) { + g.setColor(ImgUtil.randomColor(compareColor,minColorDistance)); + }else { + g.setColor(ImgUtil.randomColor()); + } } g.drawString(String.valueOf(str.charAt(i)), i * charWidth, midY); } @@ -181,8 +204,8 @@ public class GraphicsUtil { /** * 绘制图片 * - * @param g 画笔 - * @param img 要绘制的图片 + * @param g 画笔 + * @param img 要绘制的图片 * @param point 绘制的位置,基于左上角 * @return 画笔对象 */ @@ -207,11 +230,11 @@ public class GraphicsUtil { /** * 设置画笔透明度 * - * @param g 画笔 + * @param g 画笔 * @param alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字 * @return 画笔 */ - public static Graphics2D setAlpha(Graphics2D g, float alpha){ + public static Graphics2D setAlpha(Graphics2D g, float alpha) { g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); return g; } diff --git a/hutool-core/src/main/java/cn/hutool/core/img/ImgUtil.java b/hutool-core/src/main/java/cn/hutool/core/img/ImgUtil.java index df9cde7d1..f28416b82 100755 --- a/hutool-core/src/main/java/cn/hutool/core/img/ImgUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/img/ImgUtil.java @@ -2225,6 +2225,18 @@ public class ImgUtil { return ColorUtil.randomColor(); } + /** + * 生成随机颜色,与指定颜色有一定的区分度 + * + * @param compareColor 比较颜色 + * @param minDistance 最小色差,按三维坐标计算的距离值 + * @return 与指定颜色有一定的区分度的随机颜色 + * @since 5.8.30 + */ + public static Color randomColor(Color compareColor,int minDistance) { + return ColorUtil.randomColor(compareColor,minDistance); + } + /** * 生成随机颜色 *