mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
commit
d730347399
@ -1,8 +1,18 @@
|
|||||||
package cn.hutool.captcha;
|
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.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
public class CaptchaUtilTest {
|
public class CaptchaUtilTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -12,4 +22,69 @@ public class CaptchaUtilTest {
|
|||||||
CaptchaUtil.createShearCaptcha(320, 240);
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,6 +179,39 @@ public class ColorUtil {
|
|||||||
return randomColor(null);
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成随机颜色
|
* 生成随机颜色
|
||||||
*
|
*
|
||||||
|
@ -81,7 +81,24 @@ public class GraphicsUtil {
|
|||||||
* @since 4.5.10
|
* @since 4.5.10
|
||||||
*/
|
*/
|
||||||
public static Graphics drawStringColourful(Graphics g, String str, Font font, int width, int height) {
|
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 color 字体颜色,{@code null} 表示使用随机颜色(每个字符单独随机)
|
||||||
* @param width 字符串背景的宽度
|
* @param width 字符串背景的宽度
|
||||||
* @param height 字符串背景的高度
|
* @param height 字符串背景的高度
|
||||||
|
* @param compareColor 用于比对的颜色
|
||||||
|
* @param minColorDistance 随机生成的颜色与对比颜色的最小色差,小于此值则重新生成颜色
|
||||||
* @return 画笔对象
|
* @return 画笔对象
|
||||||
* @since 4.5.10
|
* @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) {
|
if (g instanceof Graphics2D) {
|
||||||
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
@ -115,7 +134,11 @@ public class GraphicsUtil {
|
|||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
if (null == color) {
|
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);
|
g.drawString(String.valueOf(str.charAt(i)), i * charWidth, midY);
|
||||||
}
|
}
|
||||||
@ -181,8 +204,8 @@ public class GraphicsUtil {
|
|||||||
/**
|
/**
|
||||||
* 绘制图片
|
* 绘制图片
|
||||||
*
|
*
|
||||||
* @param g 画笔
|
* @param g 画笔
|
||||||
* @param img 要绘制的图片
|
* @param img 要绘制的图片
|
||||||
* @param point 绘制的位置,基于左上角
|
* @param point 绘制的位置,基于左上角
|
||||||
* @return 画笔对象
|
* @return 画笔对象
|
||||||
*/
|
*/
|
||||||
@ -207,11 +230,11 @@ public class GraphicsUtil {
|
|||||||
/**
|
/**
|
||||||
* 设置画笔透明度
|
* 设置画笔透明度
|
||||||
*
|
*
|
||||||
* @param g 画笔
|
* @param g 画笔
|
||||||
* @param alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
|
* @param alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
|
||||||
* @return 画笔
|
* @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));
|
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
@ -2225,6 +2225,18 @@ public class ImgUtil {
|
|||||||
return ColorUtil.randomColor();
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成随机颜色
|
* 生成随机颜色
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user