mirror of
https://github.com/whvcse/EasyCaptcha.git
synced 2024-11-23 01:59:19 +08:00
增加内置字体,增加贝赛尔曲线干扰线
This commit is contained in:
parent
b390fe3f3f
commit
366f54ea80
@ -1,5 +1,7 @@
|
||||
package com.wf.captcha;
|
||||
|
||||
import com.wf.captcha.base.ChineseCaptchaAbstract;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
@ -58,6 +60,7 @@ public class ChineseCaptcha extends ChineseCaptchaAbstract {
|
||||
g.fillRect(0, 0, width, height);
|
||||
// 抗锯齿
|
||||
g.setColor(color());
|
||||
Font font = getFont();
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
int hp = (height - font.getSize()) >> 1;
|
||||
int h = height - hp;
|
||||
|
@ -1,5 +1,8 @@
|
||||
package com.wf.captcha;
|
||||
|
||||
import com.wf.captcha.base.ChineseCaptchaAbstract;
|
||||
import com.wf.captcha.utils.GifEncoder;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
@ -73,6 +76,7 @@ public class ChineseGifCaptcha extends ChineseCaptchaAbstract {
|
||||
g2d.setColor(fontcolor);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
// 画验证码
|
||||
Font font = getFont();
|
||||
int hp = (height - font.getSize()) >> 1;
|
||||
int h = height - hp;
|
||||
int w = width / strs.length;
|
||||
|
@ -1,5 +1,8 @@
|
||||
package com.wf.captcha;
|
||||
|
||||
import com.wf.captcha.base.Captcha;
|
||||
import com.wf.captcha.utils.GifEncoder;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
@ -84,6 +87,7 @@ public class GifCaptcha extends Captcha {
|
||||
// 随机画干扰线
|
||||
drawLine(2, g2d);
|
||||
// 画验证码
|
||||
Font font = getFont();
|
||||
int hp = (height - font.getSize()) >> 1;
|
||||
int h = height - hp;
|
||||
int w = width / strs.length;
|
||||
|
@ -1,5 +1,7 @@
|
||||
package com.wf.captcha;
|
||||
|
||||
import com.wf.captcha.base.Captcha;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
@ -40,7 +42,6 @@ public class SpecCaptcha extends Captcha {
|
||||
*/
|
||||
@Override
|
||||
public boolean out(OutputStream out) {
|
||||
checkAlpha();
|
||||
return graphicsImage(textChar(), out);
|
||||
}
|
||||
|
||||
@ -52,51 +53,51 @@ public class SpecCaptcha extends Captcha {
|
||||
* @return boolean
|
||||
*/
|
||||
private boolean graphicsImage(char[] strs, OutputStream out) {
|
||||
boolean ok;
|
||||
try {
|
||||
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = (Graphics2D) bi.getGraphics();
|
||||
// 填充背景
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(0, 0, width, height);
|
||||
// 抗锯齿
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g.setStroke(new BasicStroke(1.3f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
|
||||
// 随机画干扰线
|
||||
drawLine(3, g);
|
||||
// drawLine(3, g);
|
||||
// 随机画干扰圆
|
||||
drawOval(8, g);
|
||||
// drawOval(8, g);
|
||||
drawBesselLine(2, g);
|
||||
// 画字符串
|
||||
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;
|
||||
// AlphaComposite ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f);// 指定透明度
|
||||
// g.setComposite(ac3);
|
||||
g.setFont(getFont());
|
||||
int fontSize = getFont().getSize();
|
||||
int fY = height - ((height - fontSize) >> 1); // 文字的纵坐标
|
||||
int fW = width / strs.length; // 每一个字符所占的宽度
|
||||
int fSp = (fW - fontSize) / 2; // 字符的左右边距
|
||||
for (int i = 0; i < strs.length; i++) {
|
||||
g.setColor(new Color(20 + num(110), 20 + num(110), 20 + num(110)));
|
||||
g.setColor(color());
|
||||
// 计算坐标
|
||||
int x = i * w + sp + num(3);
|
||||
int y = h - num(3, 6);
|
||||
if (x < 8) {
|
||||
int x = i * fW + fSp;
|
||||
int y = fY/* - num(3, 6)*/;
|
||||
/*if (x < 8) {
|
||||
x = 8;
|
||||
}
|
||||
if (x + font.getSize() > width) {
|
||||
x = width - font.getSize();
|
||||
}
|
||||
if (y > height) {
|
||||
if (x + fontSize > width) {
|
||||
x = width - fontSize;
|
||||
}*/
|
||||
/*if (y > height) {
|
||||
y = height;
|
||||
}
|
||||
if (y - font.getSize() < 0) {
|
||||
y = font.getSize();
|
||||
}
|
||||
g.setFont(font.deriveFont(num(2) == 0 ? Font.PLAIN : Font.ITALIC));
|
||||
if (y - fontSize < 0) {
|
||||
y = fontSize;
|
||||
}*/
|
||||
g.drawString(String.valueOf(strs[i]), x, y);
|
||||
}
|
||||
ImageIO.write(bi, "png", out);
|
||||
out.flush();
|
||||
ok = true;
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
ok = false;
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
@ -105,6 +106,6 @@ public class SpecCaptcha extends Captcha {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,6 +1,10 @@
|
||||
package com.wf.captcha;
|
||||
package com.wf.captcha.base;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.CubicCurve2D;
|
||||
import java.awt.geom.QuadCurve2D;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
@ -8,20 +12,33 @@ 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.BOLD, 32); // 字体Verdana
|
||||
protected int len = 4; // 验证码随机字符长度
|
||||
protected int width = 130; // 验证码显示宽度
|
||||
protected int height = 48; // 验证码显示高度
|
||||
protected String chars = null; // 当前验证码
|
||||
protected int charType = TYPE_DEFAULT; // 验证码类型,1字母数字混合,2纯数字,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 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}};
|
||||
// 内置字体
|
||||
public static final int FONT_1 = 0;
|
||||
public static final int FONT_2 = 1;
|
||||
public static final int FONT_3 = 2;
|
||||
public static final int FONT_4 = 3;
|
||||
public static final int FONT_5 = 4;
|
||||
public static final int FONT_6 = 5;
|
||||
public static final int FONT_7 = 6;
|
||||
public static final int FONT_8 = 7;
|
||||
public static final int FONT_9 = 8;
|
||||
public static final int FONT_10 = 9;
|
||||
private static final String[] FONT_NAMES = new String[]{"actionj.ttf", "epilog.ttf", "fresnel.ttf", "headache.ttf", "lexo.ttf", "prefix.ttf", "progbot.ttf", "ransom.ttf", "robot.ttf", "scandal.ttf"};
|
||||
private Font font = null; // 验证码的字体
|
||||
protected int len = 5; // 验证码随机字符长度
|
||||
protected int width = 130; // 验证码显示宽度
|
||||
protected int height = 48; // 验证码显示高度
|
||||
protected int charType = TYPE_DEFAULT; // 验证码类型
|
||||
protected String chars = null; // 当前验证码
|
||||
|
||||
/**
|
||||
* 生成随机验证码
|
||||
@ -112,7 +129,7 @@ public abstract class Captcha extends Randoms {
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查验证码是否生成,没有这立即生成
|
||||
* 检查验证码是否生成,没有则立即生成
|
||||
*/
|
||||
public void checkAlpha() {
|
||||
if (chars == null) {
|
||||
@ -175,7 +192,53 @@ public abstract class Captcha extends Randoms {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机画贝塞尔曲线
|
||||
*
|
||||
* @param num 数量
|
||||
* @param g Graphics2D
|
||||
*/
|
||||
public void drawBesselLine(int num, Graphics2D g) {
|
||||
drawBesselLine(num, null, g);
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机画贝塞尔曲线
|
||||
*
|
||||
* @param num 数量
|
||||
* @param color 颜色
|
||||
* @param g Graphics2D
|
||||
*/
|
||||
public void drawBesselLine(int num, Color color, Graphics2D g) {
|
||||
for (int i = 0; i < num; i++) {
|
||||
g.setColor(color == null ? color() : color);
|
||||
int x1 = 5;
|
||||
int y1 = num(5, height - 5);
|
||||
int x2 = width - 5;
|
||||
int y2 = num(5, height - 5);
|
||||
int ctrlx = num(5, width - 5);
|
||||
int ctrly = num(5, height - 5);
|
||||
if (num(2) == 0) { // 二阶贝塞尔曲线
|
||||
QuadCurve2D shape = new QuadCurve2D.Double();
|
||||
shape.setCurve(x1, y1, ctrlx, ctrly, x2, y2);
|
||||
g.draw(shape);
|
||||
} else { // 三阶贝塞尔曲线
|
||||
int ctrlx1 = num(5, width - 5);
|
||||
int ctrly1 = num(5, height - 5);
|
||||
CubicCurve2D shape = new CubicCurve2D.Double(x1, y1, ctrlx, ctrly, ctrlx1, ctrly1, x2, y2);
|
||||
g.draw(shape);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Font getFont() {
|
||||
if (font == null) {
|
||||
try {
|
||||
setFont(FONT_1);
|
||||
} catch (Exception e) {
|
||||
setFont(new Font("Arial", Font.BOLD, 32));
|
||||
}
|
||||
}
|
||||
return font;
|
||||
}
|
||||
|
||||
@ -183,6 +246,14 @@ public abstract class Captcha extends Randoms {
|
||||
this.font = font;
|
||||
}
|
||||
|
||||
public void setFont(int font) throws IOException, FontFormatException {
|
||||
setFont(font, Font.BOLD, 32f);
|
||||
}
|
||||
|
||||
public void setFont(int font, int style, float size) throws IOException, FontFormatException {
|
||||
this.font = Font.createFont(Font.TRUETYPE_FONT, new File(getClass().getResource("/" + FONT_NAMES[font]).getFile())).deriveFont(style, size);
|
||||
}
|
||||
|
||||
public int getLen() {
|
||||
return len;
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
package com.wf.captcha;
|
||||
package com.wf.captcha.base;
|
||||
|
||||
import com.wf.captcha.base.Captcha;
|
||||
|
||||
import java.awt.*;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.wf.captcha;
|
||||
package com.wf.captcha.base;
|
||||
|
||||
import java.util.Random;
|
||||
|
@ -6,7 +6,7 @@ import java.io.IOException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.wf.captcha.Captcha;
|
||||
import com.wf.captcha.base.Captcha;
|
||||
import com.wf.captcha.GifCaptcha;
|
||||
import com.wf.captcha.SpecCaptcha;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.wf.captcha;
|
||||
package com.wf.captcha.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
@ -1,4 +1,4 @@
|
||||
package com.wf.captcha;
|
||||
package com.wf.captcha.utils;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
@ -1,4 +1,4 @@
|
||||
package com.wf.captcha;
|
||||
package com.wf.captcha.utils;
|
||||
|
||||
/**
|
||||
*
|
BIN
src/main/resources/actionj.ttf
Normal file
BIN
src/main/resources/actionj.ttf
Normal file
Binary file not shown.
BIN
src/main/resources/epilog.ttf
Normal file
BIN
src/main/resources/epilog.ttf
Normal file
Binary file not shown.
BIN
src/main/resources/fresnel.ttf
Normal file
BIN
src/main/resources/fresnel.ttf
Normal file
Binary file not shown.
BIN
src/main/resources/headache.ttf
Normal file
BIN
src/main/resources/headache.ttf
Normal file
Binary file not shown.
BIN
src/main/resources/lexo.ttf
Normal file
BIN
src/main/resources/lexo.ttf
Normal file
Binary file not shown.
BIN
src/main/resources/prefix.ttf
Normal file
BIN
src/main/resources/prefix.ttf
Normal file
Binary file not shown.
BIN
src/main/resources/progbot.ttf
Normal file
BIN
src/main/resources/progbot.ttf
Normal file
Binary file not shown.
BIN
src/main/resources/ransom.ttf
Normal file
BIN
src/main/resources/ransom.ttf
Normal file
Binary file not shown.
BIN
src/main/resources/robot.ttf
Normal file
BIN
src/main/resources/robot.ttf
Normal file
Binary file not shown.
BIN
src/main/resources/scandal.ttf
Normal file
BIN
src/main/resources/scandal.ttf
Normal file
Binary file not shown.
@ -1,9 +1,15 @@
|
||||
package com.wf.captcha;
|
||||
|
||||
import com.wf.captcha.base.Captcha;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.geom.QuadCurve2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 测试类
|
||||
@ -13,12 +19,13 @@ 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_UPPER);
|
||||
// specCaptcha.setCharType(Captcha.TYPE_ONLY_UPPER);
|
||||
System.out.println(specCaptcha.text());
|
||||
// specCaptcha.setFont(Font.createFont(Font.TRUETYPE_FONT, new File(getClass().getResource("/actionj.ttf").getFile())).deriveFont(Font.BOLD, 32));
|
||||
specCaptcha.out(new FileOutputStream(new File("D:/Java/aa" + i + ".png")));
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -48,4 +55,62 @@ public class CaptchaTest {
|
||||
}*/
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() throws Exception {
|
||||
String[] colors = new String[]{"#8cc540", "#009f5d", "#019fa0", "#019fde", "#007cdc", "#887ddd", "#cd7bdd", "#ff5675", "#ff1244", "#ff8345", "#f8bd0b", "#d1d2d4"};
|
||||
String[] fonts = new String[]{"actionj.ttf", "epilog.ttf", "fresnel.ttf", "headache.ttf", "lexo.ttf", "prefix.ttf", "progbot.ttf", "ransom.ttf", "robot.ttf", "scandal.ttf"};
|
||||
int i = 0;
|
||||
for (String f : fonts) {
|
||||
i++;
|
||||
FileOutputStream out = new FileOutputStream(new File("D:/Java/aa" + i + ".png"));
|
||||
try {
|
||||
int width = 130, height = 48;
|
||||
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = (Graphics2D) bi.getGraphics();
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(0, 0, width, height);
|
||||
// 抗锯齿
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g.setStroke(new BasicStroke(1.3f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
|
||||
// 画字符串
|
||||
float fontSize = 32f;
|
||||
Font font = Font.createFont(Font.TRUETYPE_FONT, new File(getClass().getResource("/" + f).getFile())).deriveFont(Font.BOLD, fontSize);
|
||||
g.setFont(font);
|
||||
char[] chars = "N4WbS".toCharArray();
|
||||
float sp = (width / chars.length - fontSize) / 2;
|
||||
int j = 0;
|
||||
for (char c : chars) {
|
||||
j++;
|
||||
g.setColor(Color.getColor(colors[j]));
|
||||
float x = sp * j + fontSize * (j - 1);
|
||||
float y = (height - fontSize) / 2 + fontSize;
|
||||
System.out.println(x + "-" + y);
|
||||
g.drawString(String.valueOf(c), x, y);
|
||||
}
|
||||
g.drawString("Hello", 8, 37);
|
||||
//
|
||||
QuadCurve2D shape = new QuadCurve2D.Double();
|
||||
shape.setCurve(8, 38, 38, 10, 120, 40);
|
||||
g.draw(shape);
|
||||
ImageIO.write(bi, "png", out);
|
||||
out.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3() throws Exception {
|
||||
String filePath = getClass().getResource("/actionj.ttf").getFile();
|
||||
System.out.println(filePath);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user