优化验证码效果
This commit is contained in:
parent
7defc7e727
commit
27af06eff5
2
pom.xml
2
pom.xml
@ -5,7 +5,7 @@
|
||||
<groupId>com.github.whvcse</groupId>
|
||||
|
||||
<artifactId>EasyCaptcha</artifactId>
|
||||
<version>1.4.0-RELEASE</version>
|
||||
<version>1.5.0-RELEASE</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>EasyCaptcha</name>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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); // 指定透明度
|
||||
ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f); // 指定透明度
|
||||
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);
|
||||
drawLine(2, g.getColor(), g);
|
||||
// 画干扰圆圈
|
||||
g.drawOval(num(width), num(height), 5 + num(25), 5 + num(25));
|
||||
}
|
||||
drawOval(5, g.getColor(), g);
|
||||
ImageIO.write(bi, "png", out);
|
||||
out.flush();
|
||||
ok = true;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
// 随机画干扰线
|
||||
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.setStroke(new BasicStroke(1.3f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
|
||||
// 画干扰圆圈
|
||||
g2d.setColor(color(100, 250));
|
||||
g2d.drawOval(num(width), num(height), 5 + num(25), 5 + num(25));
|
||||
}
|
||||
drawOval(4, g2d);
|
||||
// 随机画干扰线
|
||||
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();
|
||||
|
@ -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; // 小写字母最大索引
|
||||
|
||||
/**
|
||||
* 产生两个数之间的随机数
|
||||
|
@ -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);
|
||||
|
@ -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")));
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user