mirror of
https://github.com/whvcse/EasyCaptcha.git
synced 2024-11-23 10:09:19 +08:00
优化验证码效果
This commit is contained in:
parent
74a1991352
commit
92af7138a9
@ -140,7 +140,7 @@ public class LoginController {
|
|||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
public JsonResult login(String username,String password,String code){
|
public JsonResult login(String username,String password,String code){
|
||||||
|
|
||||||
if (CaptchaUtil.ver(code, request)) {
|
if (!CaptchaUtil.ver(code, request)) {
|
||||||
CaptchaUtil.clear(request);
|
CaptchaUtil.clear(request);
|
||||||
return JsonResult.error("验证码不正确");
|
return JsonResult.error("验证码不正确");
|
||||||
}
|
}
|
||||||
|
2
pom.xml
2
pom.xml
@ -5,7 +5,7 @@
|
|||||||
<groupId>com.github.whvcse</groupId>
|
<groupId>com.github.whvcse</groupId>
|
||||||
|
|
||||||
<artifactId>EasyCaptcha</artifactId>
|
<artifactId>EasyCaptcha</artifactId>
|
||||||
<version>1.3.0-RELEASE</version>
|
<version>1.3.1-RELEASE</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>EasyCaptcha</name>
|
<name>EasyCaptcha</name>
|
||||||
|
@ -9,7 +9,7 @@ import java.io.OutputStream;
|
|||||||
* Created by 王帆 on 2018-07-27 上午 10:08.
|
* Created by 王帆 on 2018-07-27 上午 10:08.
|
||||||
*/
|
*/
|
||||||
public abstract class Captcha extends Randoms {
|
public abstract class Captcha extends Randoms {
|
||||||
protected Font font = new Font("Verdana", Font.PLAIN, 32); // 字体
|
protected Font font = new Font("Arial", Font.PLAIN, 32); // 字体Verdana
|
||||||
protected int len = 5; // 验证码随机字符长度
|
protected int len = 5; // 验证码随机字符长度
|
||||||
protected int width = 130; // 验证码显示宽度
|
protected int width = 130; // 验证码显示宽度
|
||||||
protected int height = 48; // 验证码显示高度
|
protected int height = 48; // 验证码显示高度
|
||||||
@ -17,11 +17,10 @@ public abstract class Captcha extends Randoms {
|
|||||||
protected int charType = TYPE_DEFAULT; // 验证码类型,1字母数字混合,2纯数字,3纯字母
|
protected int charType = TYPE_DEFAULT; // 验证码类型,1字母数字混合,2纯数字,3纯字母
|
||||||
public static final int TYPE_DEFAULT = 1; // 字母数字混合
|
public static final int TYPE_DEFAULT = 1; // 字母数字混合
|
||||||
public static final int TYPE_ONLY_NUMBER = 2; // 纯数字
|
public static final int TYPE_ONLY_NUMBER = 2; // 纯数字
|
||||||
public static final int TYPE_ONLY_CHAR = 3; // 纯字母 // 常用颜色
|
public static final int TYPE_ONLY_CHAR = 3; // 纯字母
|
||||||
// 常用颜色
|
// 常用颜色
|
||||||
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}};
|
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}};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成随机验证码
|
* 生成随机验证码
|
||||||
*
|
*
|
||||||
|
@ -67,8 +67,8 @@ public class ChineseCaptcha extends ChineseCaptchaAbstract {
|
|||||||
// 画字符串
|
// 画字符串
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
// 计算坐标
|
// 计算坐标
|
||||||
int x = i * w + sp + num(-Math.abs(sp), Math.abs(sp));
|
int x = i * w + sp + num(-5, 5);
|
||||||
int y = h + num(-Math.abs(hp), Math.abs(hp));
|
int y = h + num(-5, 5);
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
x = 0;
|
x = 0;
|
||||||
}
|
}
|
||||||
|
@ -68,8 +68,8 @@ public class ChineseGifCaptcha extends ChineseCaptchaAbstract {
|
|||||||
Graphics2D g2d = (Graphics2D) image.getGraphics();
|
Graphics2D g2d = (Graphics2D) image.getGraphics();
|
||||||
g2d.setColor(Color.WHITE); // 填充背景颜色
|
g2d.setColor(Color.WHITE); // 填充背景颜色
|
||||||
g2d.fillRect(0, 0, width, height);
|
g2d.fillRect(0, 0, width, height);
|
||||||
AlphaComposite ac3;
|
|
||||||
// 抗锯齿
|
// 抗锯齿
|
||||||
|
AlphaComposite ac3;
|
||||||
g2d.setColor(fontcolor);
|
g2d.setColor(fontcolor);
|
||||||
g2d.setFont(font);
|
g2d.setFont(font);
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
@ -82,7 +82,7 @@ public class ChineseGifCaptcha extends ChineseCaptchaAbstract {
|
|||||||
ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getAlpha(flag, i));
|
ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getAlpha(flag, i));
|
||||||
g2d.setComposite(ac3);
|
g2d.setComposite(ac3);
|
||||||
// 计算坐标
|
// 计算坐标
|
||||||
int x = i * w + sp + num(-Math.abs(sp), Math.abs(sp));
|
int x = i * w + sp + num(-3, 3);
|
||||||
int y = h + num(-3, 3);
|
int y = h + num(-3, 3);
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
x = 0;
|
x = 0;
|
||||||
@ -99,17 +99,19 @@ public class ChineseGifCaptcha extends ChineseCaptchaAbstract {
|
|||||||
g2d.drawString(String.valueOf(strs[i]), x, y);
|
g2d.drawString(String.valueOf(strs[i]), x, y);
|
||||||
}
|
}
|
||||||
// 随机画干扰线
|
// 随机画干扰线
|
||||||
g2d.setStroke(new BasicStroke(1.2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
|
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++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.55f);
|
|
||||||
g2d.setComposite(ac3);
|
|
||||||
int x1 = num(-10, width - 10);
|
int x1 = num(-10, width - 10);
|
||||||
int y1 = num(5, height - 5);
|
int y1 = num(5, height - 5);
|
||||||
int x2 = num(10, width + 10);
|
int x2 = num(10, width + 10);
|
||||||
int y2 = num(2, height - 2);
|
int y2 = num(2, height - 2);
|
||||||
g2d.drawLine(x1, y1, x2, y2);
|
g2d.drawLine(x1, y1, x2, y2);
|
||||||
// 画干扰圆圈
|
}
|
||||||
g2d.drawOval(num(width), num(height), 5 + num(10), 5 + num(10));
|
// 画干扰圆圈
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
g2d.drawOval(num(width), num(height), 5 + num(50), 5 + num(50));
|
||||||
}
|
}
|
||||||
g2d.dispose();
|
g2d.dispose();
|
||||||
return image;
|
return image;
|
||||||
@ -124,7 +126,8 @@ public class ChineseGifCaptcha extends ChineseCaptchaAbstract {
|
|||||||
*/
|
*/
|
||||||
private float getAlpha(int i, int j) {
|
private float getAlpha(int i, int j) {
|
||||||
int num = i + j;
|
int num = i + j;
|
||||||
float r = (float) 1 / len, s = (len + 1) * r;
|
float r = (float) 1 / (len - 1);
|
||||||
return num > len ? (num * r - s) : num * r;
|
float s = len * r;
|
||||||
|
return num >= len ? (num * r - s) : num * r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,14 +96,14 @@ public class GifCaptcha extends Captcha {
|
|||||||
int hp = (height - font.getSize()) >> 1;
|
int hp = (height - font.getSize()) >> 1;
|
||||||
int h = height - hp;
|
int h = height - hp;
|
||||||
int w = width / strs.length;
|
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++) {
|
for (int i = 0; i < strs.length; i++) {
|
||||||
AlphaComposite ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getAlpha(flag, i));
|
AlphaComposite ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getAlpha(flag, i));
|
||||||
g2d.setComposite(ac3);
|
g2d.setComposite(ac3);
|
||||||
g2d.setColor(fontcolor[i]);
|
g2d.setColor(fontcolor[i]);
|
||||||
// 计算坐标
|
// 计算坐标
|
||||||
int x = i * w + sp + num(-3, 3);
|
int x = i * w + num(6);
|
||||||
int y = h + num(-6, 0);
|
int y = h - num(2, 8);
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
x = 0;
|
x = 0;
|
||||||
}
|
}
|
||||||
@ -131,8 +131,9 @@ public class GifCaptcha extends Captcha {
|
|||||||
*/
|
*/
|
||||||
private float getAlpha(int i, int j) {
|
private float getAlpha(int i, int j) {
|
||||||
int num = i + j;
|
int num = i + j;
|
||||||
float r = (float) 1 / len, s = (len + 1) * r;
|
float r = (float) 1 / (len - 1);
|
||||||
return num > len ? (num * r - s) : num * r;
|
float s = len * r;
|
||||||
|
return num >= len ? (num * r - s) : num * r;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -81,12 +81,12 @@ public class SpecCaptcha extends Captcha {
|
|||||||
int hp = (height - font.getSize()) >> 1;
|
int hp = (height - font.getSize()) >> 1;
|
||||||
int h = height - hp;
|
int h = height - hp;
|
||||||
int w = width / strs.length;
|
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++) {
|
for (int i = 0; i < strs.length; i++) {
|
||||||
g.setColor(new Color(20 + num(110), 20 + num(110), 20 + num(110)));
|
g.setColor(new Color(20 + num(110), 20 + num(110), 20 + num(110)));
|
||||||
// 计算坐标
|
// 计算坐标
|
||||||
int x = i * w + sp + num(-Math.abs(sp), Math.abs(sp));
|
int x = i * w + num(10);
|
||||||
int y = h + num(-Math.abs(hp), Math.abs(hp));
|
int y = h - num(9);
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
x = 0;
|
x = 0;
|
||||||
}
|
}
|
||||||
@ -99,7 +99,6 @@ public class SpecCaptcha extends Captcha {
|
|||||||
if (y - font.getSize() < 0) {
|
if (y - font.getSize() < 0) {
|
||||||
y = font.getSize();
|
y = font.getSize();
|
||||||
}
|
}
|
||||||
System.out.println(x + "--" + y);
|
|
||||||
g.drawString(String.valueOf(strs[i]), x, y);
|
g.drawString(String.valueOf(strs[i]), x, y);
|
||||||
}
|
}
|
||||||
ImageIO.write(bi, "png", out);
|
ImageIO.write(bi, "png", out);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.wf.captcha.utils;
|
package com.wf.captcha.utils;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
@ -7,6 +8,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
|
|
||||||
import com.wf.captcha.Captcha;
|
import com.wf.captcha.Captcha;
|
||||||
import com.wf.captcha.GifCaptcha;
|
import com.wf.captcha.GifCaptcha;
|
||||||
|
import com.wf.captcha.SpecCaptcha;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 图形验证码工具类
|
* 图形验证码工具类
|
||||||
@ -55,6 +57,20 @@ public class CaptchaUtil {
|
|||||||
out(130, 48, len, request, response);
|
out(130, 48, len, request, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出验证码
|
||||||
|
*
|
||||||
|
* @param len 长度
|
||||||
|
* @param font 字体
|
||||||
|
* @param request HttpServletRequest
|
||||||
|
* @param response HttpServletResponse
|
||||||
|
* @throws IOException IO异常
|
||||||
|
*/
|
||||||
|
public static void out(int len, Font font, HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws IOException {
|
||||||
|
out(130, 48, len, font, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输出验证码
|
* 输出验证码
|
||||||
*
|
*
|
||||||
@ -67,8 +83,119 @@ public class CaptchaUtil {
|
|||||||
*/
|
*/
|
||||||
public static void out(int width, int height, int len, HttpServletRequest request, HttpServletResponse response)
|
public static void out(int width, int height, int len, HttpServletRequest request, HttpServletResponse response)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
out(width, height, len, null, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出验证码
|
||||||
|
*
|
||||||
|
* @param width 宽度
|
||||||
|
* @param height 高度
|
||||||
|
* @param len 长度
|
||||||
|
* @param font 字体
|
||||||
|
* @param request HttpServletRequest
|
||||||
|
* @param response HttpServletResponse
|
||||||
|
* @throws IOException IO异常
|
||||||
|
*/
|
||||||
|
public static void out(int width, int height, int len, Font font, HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws IOException {
|
||||||
|
outCaptcha(width, height, len, font, 1, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出验证码
|
||||||
|
*
|
||||||
|
* @param request HttpServletRequest
|
||||||
|
* @param response HttpServletResponse
|
||||||
|
* @throws IOException IO异常
|
||||||
|
*/
|
||||||
|
public static void outPng(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws IOException {
|
||||||
|
outPng(5, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出验证码
|
||||||
|
*
|
||||||
|
* @param len 长度
|
||||||
|
* @param request HttpServletRequest
|
||||||
|
* @param response HttpServletResponse
|
||||||
|
* @throws IOException IO异常
|
||||||
|
*/
|
||||||
|
public static void outPng(int len, HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws IOException {
|
||||||
|
outPng(130, 48, len, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出验证码
|
||||||
|
*
|
||||||
|
* @param len 长度
|
||||||
|
* @param font 字体
|
||||||
|
* @param request HttpServletRequest
|
||||||
|
* @param response HttpServletResponse
|
||||||
|
* @throws IOException IO异常
|
||||||
|
*/
|
||||||
|
public static void outPng(int len, Font font, HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws IOException {
|
||||||
|
outPng(130, 48, len, font, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出验证码
|
||||||
|
*
|
||||||
|
* @param width 宽度
|
||||||
|
* @param height 高度
|
||||||
|
* @param len 长度
|
||||||
|
* @param request HttpServletRequest
|
||||||
|
* @param response HttpServletResponse
|
||||||
|
* @throws IOException IO异常
|
||||||
|
*/
|
||||||
|
public static void outPng(int width, int height, int len, HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws IOException {
|
||||||
|
outPng(width, height, len, null, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出验证码
|
||||||
|
*
|
||||||
|
* @param width 宽度
|
||||||
|
* @param height 高度
|
||||||
|
* @param len 长度
|
||||||
|
* @param font 字体
|
||||||
|
* @param request HttpServletRequest
|
||||||
|
* @param response HttpServletResponse
|
||||||
|
* @throws IOException IO异常
|
||||||
|
*/
|
||||||
|
public static void outPng(int width, int height, int len, Font font, HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws IOException {
|
||||||
|
outCaptcha(width, height, len, font, 0, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出验证码
|
||||||
|
*
|
||||||
|
* @param width 宽度
|
||||||
|
* @param height 高度
|
||||||
|
* @param len 长度
|
||||||
|
* @param font 字体
|
||||||
|
* @param cType 类型
|
||||||
|
* @param request HttpServletRequest
|
||||||
|
* @param response HttpServletResponse
|
||||||
|
* @throws IOException IO异常
|
||||||
|
*/
|
||||||
|
private static void outCaptcha(int width, int height, int len, Font font, int cType, HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws IOException {
|
||||||
setHeader(response);
|
setHeader(response);
|
||||||
Captcha captcha = new GifCaptcha(width, height, len);
|
Captcha captcha = null;
|
||||||
|
if (cType == 0) {
|
||||||
|
captcha = new SpecCaptcha(width, height, len);
|
||||||
|
} else if (cType == 1) {
|
||||||
|
captcha = new GifCaptcha(width, height, len);
|
||||||
|
}
|
||||||
|
if (font != null) {
|
||||||
|
captcha.setFont(font);
|
||||||
|
}
|
||||||
request.getSession().setAttribute(SESSION_KEY, captcha.text().toLowerCase());
|
request.getSession().setAttribute(SESSION_KEY, captcha.text().toLowerCase());
|
||||||
captcha.out(response.getOutputStream());
|
captcha.out(response.getOutputStream());
|
||||||
}
|
}
|
||||||
|
@ -17,16 +17,16 @@ public class CaptchaTest {
|
|||||||
SpecCaptcha specCaptcha = new SpecCaptcha();
|
SpecCaptcha specCaptcha = new SpecCaptcha();
|
||||||
//specCaptcha.setCharType(Captcha.TYPE_ONLY_NUMBER);
|
//specCaptcha.setCharType(Captcha.TYPE_ONLY_NUMBER);
|
||||||
System.out.println(specCaptcha.text());
|
System.out.println(specCaptcha.text());
|
||||||
// specCaptcha.out(new FileOutputStream(new File("C:/Java/aa" + i + ".png")));
|
specCaptcha.out(new FileOutputStream(new File("D:/Java/aa" + i + ".png")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGIf() throws Exception {
|
public void testGIf() throws Exception {
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
GifCaptcha gifCaptcha = new GifCaptcha(130, 48, 5);
|
GifCaptcha gifCaptcha = new GifCaptcha();
|
||||||
System.out.println(gifCaptcha.text());
|
System.out.println(gifCaptcha.text());
|
||||||
// gifCaptcha.out(new FileOutputStream(new File("C:/Java/aa" + i + ".gif")));
|
gifCaptcha.out(new FileOutputStream(new File("D:/Java/aa" + i + ".gif")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ public class CaptchaTest {
|
|||||||
ChineseCaptcha chineseCaptcha = new ChineseCaptcha();
|
ChineseCaptcha chineseCaptcha = new ChineseCaptcha();
|
||||||
//chineseCaptcha.setFont(new Font("微软雅黑", Font.PLAIN, 25));
|
//chineseCaptcha.setFont(new Font("微软雅黑", Font.PLAIN, 25));
|
||||||
System.out.println(chineseCaptcha.text());
|
System.out.println(chineseCaptcha.text());
|
||||||
//chineseCaptcha.out(new FileOutputStream(new File("C:/Java/aa.png")));
|
chineseCaptcha.out(new FileOutputStream(new File("D:/Java/aa.png")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -43,7 +43,7 @@ public class CaptchaTest {
|
|||||||
ChineseGifCaptcha chineseGifCaptcha = new ChineseGifCaptcha();
|
ChineseGifCaptcha chineseGifCaptcha = new ChineseGifCaptcha();
|
||||||
//chineseGifCaptcha.setFont(new Font("微软雅黑", Font.PLAIN, 30));
|
//chineseGifCaptcha.setFont(new Font("微软雅黑", Font.PLAIN, 30));
|
||||||
System.out.println(chineseGifCaptcha.text());
|
System.out.println(chineseGifCaptcha.text());
|
||||||
//chineseGifCaptcha.out(new FileOutputStream(new File("C:/Java/aa.gif")));
|
chineseGifCaptcha.out(new FileOutputStream(new File("D:/Java/aa.gif")));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user