diff --git a/pom.xml b/pom.xml
index 1e40aad..4206d22 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.github.whvcse
EasyCaptcha
- 1.4.0-RELEASE
+ 1.5.0-RELEASE
jar
EasyCaptcha
diff --git a/src/main/java/com/wf/captcha/Captcha.java b/src/main/java/com/wf/captcha/Captcha.java
index 9b1089a..2fbb633 100644
--- a/src/main/java/com/wf/captcha/Captcha.java
+++ b/src/main/java/com/wf/captcha/Captcha.java
@@ -1,7 +1,6 @@
package com.wf.captcha;
-import java.awt.Color;
-import java.awt.Font;
+import java.awt.*;
import java.io.OutputStream;
/**
@@ -9,8 +8,8 @@ import java.io.OutputStream;
* Created by 王帆 on 2018-07-27 上午 10:08.
*/
public abstract class Captcha extends Randoms {
- protected Font font = new Font("Arial", Font.PLAIN, 32); // 字体Verdana
- protected int len = 5; // 验证码随机字符长度
+ protected Font font = new Font("Arial", Font.BOLD, 32); // 字体Verdana
+ protected int len = 4; // 验证码随机字符长度
protected int width = 130; // 验证码显示宽度
protected int height = 48; // 验证码显示高度
protected String chars = null; // 当前验证码
@@ -18,6 +17,9 @@ public abstract class Captcha extends Randoms {
public static final int TYPE_DEFAULT = 1; // 字母数字混合
public static final int TYPE_ONLY_NUMBER = 2; // 纯数字
public static final int TYPE_ONLY_CHAR = 3; // 纯字母
+ public static final int TYPE_ONLY_UPPER = 4; // 纯大写字母
+ public static final int TYPE_ONLY_LOWER = 5; // 纯小写字母
+ public static final int TYPE_NUM_AND_UPPER = 6; // 数字大写字母
// 常用颜色
public static final int[][] COLOR = {{0, 135, 255}, {51, 153, 51}, {255, 102, 102}, {255, 153, 0}, {153, 102, 0}, {153, 102, 153}, {51, 153, 153}, {102, 102, 255}, {0, 102, 204}, {204, 51, 51}, {0, 153, 204}, {0, 51, 102}};
@@ -36,6 +38,15 @@ public abstract class Captcha extends Randoms {
case 3:
cs[i] = alpha(charMinIndex, charMaxIndex);
break;
+ case 4:
+ cs[i] = alpha(upperMinIndex, upperMaxIndex);
+ break;
+ case 5:
+ cs[i] = alpha(lowerMinIndex, lowerMaxIndex);
+ break;
+ case 6:
+ cs[i] = alpha(upperMaxIndex);
+ break;
default:
cs[i] = alpha();
}
@@ -109,6 +120,61 @@ public abstract class Captcha extends Randoms {
}
}
+ /**
+ * 随机画干扰线
+ *
+ * @param num 数量
+ * @param g Graphics2D
+ */
+ public void drawLine(int num, Graphics2D g) {
+ drawLine(num, null, g);
+ }
+
+ /**
+ * 随机画干扰线
+ *
+ * @param num 数量
+ * @param color 颜色
+ * @param g Graphics2D
+ */
+ public void drawLine(int num, Color color, Graphics2D g) {
+ for (int i = 0; i < num; i++) {
+ g.setColor(color == null ? color(150, 250) : color);
+ int x1 = num(-10, width - 10);
+ int y1 = num(5, height - 5);
+ int x2 = num(10, width + 10);
+ int y2 = num(2, height - 2);
+ g.drawLine(x1, y1, x2, y2);
+ }
+ }
+
+ /**
+ * 随机画干扰圆
+ *
+ * @param num 数量
+ * @param g Graphics2D
+ */
+ public void drawOval(int num, Graphics2D g) {
+ for (int i = 0; i < num; i++) {
+ g.setColor(color(100, 250));
+ g.drawOval(num(width), num(height), 10 + num(20), 10 + num(20));
+ }
+ }
+
+ /**
+ * 随机画干扰圆
+ *
+ * @param num 数量
+ * @param color 颜色
+ * @param g Graphics2D
+ */
+ public void drawOval(int num, Color color, Graphics2D g) {
+ for (int i = 0; i < num; i++) {
+ g.setColor(color == null ? color(100, 250) : color);
+ g.drawOval(num(width), num(height), 10 + num(20), 10 + num(20));
+ }
+ }
+
public Font getFont() {
return font;
}
diff --git a/src/main/java/com/wf/captcha/ChineseCaptcha.java b/src/main/java/com/wf/captcha/ChineseCaptcha.java
index 6af6d84..6d524a3 100644
--- a/src/main/java/com/wf/captcha/ChineseCaptcha.java
+++ b/src/main/java/com/wf/captcha/ChineseCaptcha.java
@@ -58,7 +58,6 @@ public class ChineseCaptcha extends ChineseCaptchaAbstract {
g.fillRect(0, 0, width, height);
// 抗锯齿
g.setColor(color());
- g.setFont(font);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int hp = (height - font.getSize()) >> 1;
int h = height - hp;
@@ -69,8 +68,8 @@ public class ChineseCaptcha extends ChineseCaptchaAbstract {
// 计算坐标
int x = i * w + sp + num(-5, 5);
int y = h + num(-5, 5);
- if (x < 0) {
- x = 0;
+ if (x < 5) {
+ x = 5;
}
if (x + font.getSize() > width) {
x = width - font.getSize();
@@ -81,21 +80,16 @@ public class ChineseCaptcha extends ChineseCaptchaAbstract {
if (y - font.getSize() < 0) {
y = font.getSize();
}
+ g.setFont(font.deriveFont(num(2) == 0 ? Font.PLAIN : Font.ITALIC));
g.drawString(String.valueOf(strs[i]), x, y);
}
// 随机画干扰线
g.setStroke(new BasicStroke(1.25f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
- for (int i = 0; i < 6; i++) {
- ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.75f); // 指定透明度
- g.setComposite(ac3);
- int x1 = num(-10, width - 10);
- int y1 = num(5, height - 5);
- int x2 = num(10, width + 10);
- int y2 = num(2, height - 2);
- g.drawLine(x1, y1, x2, y2);
- // 画干扰圆圈
- g.drawOval(num(width), num(height), 5 + num(25), 5 + num(25));
- }
+ ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f); // 指定透明度
+ g.setComposite(ac3);
+ drawLine(2, g.getColor(), g);
+ // 画干扰圆圈
+ drawOval(5, g.getColor(), g);
ImageIO.write(bi, "png", out);
out.flush();
ok = true;
diff --git a/src/main/java/com/wf/captcha/ChineseCaptchaAbstract.java b/src/main/java/com/wf/captcha/ChineseCaptchaAbstract.java
index e64e0ff..edc0e2d 100644
--- a/src/main/java/com/wf/captcha/ChineseCaptchaAbstract.java
+++ b/src/main/java/com/wf/captcha/ChineseCaptchaAbstract.java
@@ -35,4 +35,16 @@ public abstract class ChineseCaptchaAbstract extends Captcha {
return DELTA.charAt(num(DELTA.length()));
}
+
+ @Override
+ public void drawLine(int num, Color color, Graphics2D g) {
+ for (int i = 0; i < num; i++) {
+ g.setColor(color == null ? color(150, 250) : color);
+ int x1 = num(-10, width / 3);
+ int y1 = num(5, height - 5);
+ int x2 = num(width / 3 * 2, width + 10);
+ int y2 = num(2, height - 2);
+ g.drawLine(x1, y1, x2, y2);
+ }
+ }
}
diff --git a/src/main/java/com/wf/captcha/ChineseGifCaptcha.java b/src/main/java/com/wf/captcha/ChineseGifCaptcha.java
index 38c44af..dc6e12c 100644
--- a/src/main/java/com/wf/captcha/ChineseGifCaptcha.java
+++ b/src/main/java/com/wf/captcha/ChineseGifCaptcha.java
@@ -28,7 +28,7 @@ public class ChineseGifCaptcha extends ChineseCaptchaAbstract {
@Override
public boolean out(OutputStream os) {
checkAlpha();
- boolean ok = false;
+ boolean ok;
try {
char[] rands = textChar(); // 获取验证码数组
GifEncoder gifEncoder = new GifEncoder();
@@ -71,7 +71,6 @@ public class ChineseGifCaptcha extends ChineseCaptchaAbstract {
// 抗锯齿
AlphaComposite ac3;
g2d.setColor(fontcolor);
- g2d.setFont(font);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 画验证码
int hp = (height - font.getSize()) >> 1;
@@ -96,23 +95,16 @@ public class ChineseGifCaptcha extends ChineseCaptchaAbstract {
if (y - font.getSize() < 0) {
y = font.getSize();
}
+ g2d.setFont(font.deriveFont(num(2) == 0 ? Font.PLAIN : Font.ITALIC));
g2d.drawString(String.valueOf(strs[i]), x, y);
}
// 随机画干扰线
g2d.setStroke(new BasicStroke(1.25f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.45f);
g2d.setComposite(ac3);
- for (int i = 0; i < 4; i++) {
- int x1 = num(-10, width - 10);
- int y1 = num(5, height - 5);
- int x2 = num(10, width + 10);
- int y2 = num(2, height - 2);
- g2d.drawLine(x1, y1, x2, y2);
- }
+ drawLine(1, g2d.getColor(), g2d);
// 画干扰圆圈
- for (int i = 0; i < 8; i++) {
- g2d.drawOval(num(width), num(height), 5 + num(50), 5 + num(50));
- }
+ drawOval(3, g2d.getColor(), g2d);
g2d.dispose();
return image;
}
diff --git a/src/main/java/com/wf/captcha/GifCaptcha.java b/src/main/java/com/wf/captcha/GifCaptcha.java
index a88adf6..e4f870d 100644
--- a/src/main/java/com/wf/captcha/GifCaptcha.java
+++ b/src/main/java/com/wf/captcha/GifCaptcha.java
@@ -32,7 +32,7 @@ public class GifCaptcha extends Captcha {
@Override
public boolean out(OutputStream os) {
checkAlpha();
- boolean ok = false;
+ boolean ok;
try {
char[] rands = textChar(); // 获取验证码数组
GifEncoder gifEncoder = new GifEncoder();
@@ -77,35 +77,27 @@ public class GifCaptcha extends Captcha {
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height);
// 抗锯齿
- g2d.setFont(font);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g2d.setStroke(new BasicStroke(1.3f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
+ // 画干扰圆圈
+ drawOval(4, g2d);
// 随机画干扰线
- for (int i = 0; i < num(5, 12); i++) {
- g2d.setStroke(new BasicStroke(1.1f + RANDOM.nextFloat() / 2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
- g2d.setColor(color(150, 250));
- int x1 = num(-10, width - 10);
- int y1 = num(5, height - 5);
- int x2 = num(10, width + 10);
- int y2 = num(2, height - 2);
- g2d.drawLine(x1, y1, x2, y2);
- // 画干扰圆圈
- g2d.setColor(color(100, 250));
- g2d.drawOval(num(width), num(height), 5 + num(25), 5 + num(25));
- }
+ drawLine(2, g2d);
// 画验证码
int hp = (height - font.getSize()) >> 1;
int h = height - hp;
int w = width / strs.length;
- //int sp = (w - font.getSize()) / 2;
+ int sp = (w - font.getSize()) / 2;
for (int i = 0; i < strs.length; i++) {
AlphaComposite ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getAlpha(flag, i));
g2d.setComposite(ac3);
g2d.setColor(fontcolor[i]);
// 计算坐标
- int x = i * w + num(6);
- int y = h - num(2, 8);
- if (x < 0) {
- x = 0;
+ int x = i * w + sp + num(3);
+ int y = h - num(3, 6);
+ // 调整溢出的字
+ if (x < 8) {
+ x = 8;
}
if (x + font.getSize() > width) {
x = width - font.getSize();
@@ -116,6 +108,7 @@ public class GifCaptcha extends Captcha {
if (y - font.getSize() < 0) {
y = font.getSize();
}
+ g2d.setFont(font.deriveFont(num(2) == 0 ? Font.PLAIN : Font.ITALIC));
g2d.drawString(String.valueOf(strs[i]), x, y);
}
g2d.dispose();
diff --git a/src/main/java/com/wf/captcha/Randoms.java b/src/main/java/com/wf/captcha/Randoms.java
index 06a62c4..1771a48 100644
--- a/src/main/java/com/wf/captcha/Randoms.java
+++ b/src/main/java/com/wf/captcha/Randoms.java
@@ -15,6 +15,10 @@ public class Randoms {
protected static final int numMaxIndex = 8; // 数字的最大索引,不包括最大值
protected static final int charMinIndex = numMaxIndex; // 字符的最小索引,包括最小值
protected static final int charMaxIndex = ALPHA.length; // 字符的最大索引,不包括最大值
+ protected static final int upperMinIndex = charMinIndex; // 大写字符最小索引
+ protected static final int upperMaxIndex = upperMinIndex + 23; // 大写字符最大索引
+ protected static final int lowerMinIndex = upperMaxIndex; // 小写字母最小索引
+ protected static final int lowerMaxIndex = charMaxIndex; // 小写字母最大索引
/**
* 产生两个数之间的随机数
diff --git a/src/main/java/com/wf/captcha/SpecCaptcha.java b/src/main/java/com/wf/captcha/SpecCaptcha.java
index 92d98b1..9a78684 100644
--- a/src/main/java/com/wf/captcha/SpecCaptcha.java
+++ b/src/main/java/com/wf/captcha/SpecCaptcha.java
@@ -14,7 +14,6 @@ import javax.imageio.ImageIO;
public class SpecCaptcha extends Captcha {
public SpecCaptcha() {
- setFont(new Font(font.getFontName(), Font.ITALIC, font.getSize()));
}
public SpecCaptcha(int width, int height) {
@@ -60,35 +59,26 @@ public class SpecCaptcha extends Captcha {
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
// 抗锯齿
- g.setFont(font);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g.setStroke(new BasicStroke(1.3f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
// 随机画干扰线
- for (int i = 0; i < 12; i++) {
- g.setColor(color(150, 250));
- g.setStroke(new BasicStroke(1.1f + RANDOM.nextFloat() / 2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
- int x1 = num(-10, width - 10);
- int y1 = num(5, height - 5);
- int x2 = num(10, width + 10);
- int y2 = num(2, height - 2);
- g.drawLine(x1, y1, x2, y2);
- // 画干扰圆圈
- g.setColor(color(100, 250));
- g.drawOval(num(width), num(height), 5 + num(25), 5 + num(25));
- }
+ drawLine(3, g);
+ // 随机画干扰圆
+ drawOval(8, g);
// 画字符串
- AlphaComposite ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.75f);// 指定透明度
+ AlphaComposite ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f);// 指定透明度
g.setComposite(ac3);
int hp = (height - font.getSize()) >> 1;
int h = height - hp;
int w = width / strs.length;
- //int sp = (w - font.getSize()) / 2;
+ int sp = (w - font.getSize()) / 2;
for (int i = 0; i < strs.length; i++) {
g.setColor(new Color(20 + num(110), 20 + num(110), 20 + num(110)));
// 计算坐标
- int x = i * w + num(10);
- int y = h - num(9);
- if (x < 0) {
- x = 0;
+ int x = i * w + sp + num(3);
+ int y = h - num(3, 6);
+ if (x < 8) {
+ x = 8;
}
if (x + font.getSize() > width) {
x = width - font.getSize();
@@ -99,6 +89,7 @@ public class SpecCaptcha extends Captcha {
if (y - font.getSize() < 0) {
y = font.getSize();
}
+ g.setFont(font.deriveFont(num(2) == 0 ? Font.PLAIN : Font.ITALIC));
g.drawString(String.valueOf(strs[i]), x, y);
}
ImageIO.write(bi, "png", out);
diff --git a/src/test/java/com/wf/captcha/CaptchaTest.java b/src/test/java/com/wf/captcha/CaptchaTest.java
index e75818d..3900b1f 100644
--- a/src/test/java/com/wf/captcha/CaptchaTest.java
+++ b/src/test/java/com/wf/captcha/CaptchaTest.java
@@ -13,37 +13,39 @@ public class CaptchaTest {
@Test
public void test() throws Exception {
- for (int i = 0; i < 5; i++) {
+ /*for (int i = 0; i < 5; i++) {
SpecCaptcha specCaptcha = new SpecCaptcha();
- //specCaptcha.setCharType(Captcha.TYPE_ONLY_NUMBER);
+ specCaptcha.setCharType(Captcha.TYPE_ONLY_UPPER);
System.out.println(specCaptcha.text());
- //specCaptcha.out(new FileOutputStream(new File("D:/Java/aa" + i + ".png")));
- }
+ specCaptcha.out(new FileOutputStream(new File("D:/Java/aa" + i + ".png")));
+ }*/
}
@Test
public void testGIf() throws Exception {
- for (int i = 0; i < 5; i++) {
+ /*for (int i = 0; i < 5; i++) {
GifCaptcha gifCaptcha = new GifCaptcha();
System.out.println(gifCaptcha.text());
- //gifCaptcha.out(new FileOutputStream(new File("D:/Java/aa" + i + ".gif")));
- }
+ gifCaptcha.out(new FileOutputStream(new File("D:/Java/aa" + i + ".gif")));
+ }*/
}
@Test
public void testHan() throws Exception {
- // ChineseCaptcha chineseCaptcha = new ChineseCaptcha();
- //chineseCaptcha.setFont(new Font("微软雅黑", Font.PLAIN, 25));
- // System.out.println(chineseCaptcha.text());
- //chineseCaptcha.out(new FileOutputStream(new File("D:/Java/aa.png")));
+ /*for (int i = 0; i < 5; i++) {
+ ChineseCaptcha chineseCaptcha = new ChineseCaptcha();
+ System.out.println(chineseCaptcha.text());
+ chineseCaptcha.out(new FileOutputStream(new File("D:/Java/aa" + i + ".png")));
+ }*/
}
@Test
public void testGifHan() throws Exception {
- // ChineseGifCaptcha chineseGifCaptcha = new ChineseGifCaptcha();
- //chineseGifCaptcha.setFont(new Font("微软雅黑", Font.PLAIN, 30));
- // System.out.println(chineseGifCaptcha.text());
- //chineseGifCaptcha.out(new FileOutputStream(new File("D:/Java/aa.gif")));
+ /*for (int i = 0; i < 5; i++) {
+ ChineseGifCaptcha chineseGifCaptcha = new ChineseGifCaptcha();
+ System.out.println(chineseGifCaptcha.text());
+ chineseGifCaptcha.out(new FileOutputStream(new File("D:/Java/aa" + i + ".gif")));
+ }*/
}
}