增加内置字体,增加贝赛尔曲线干扰线

pull/12/head
whvcse@foxmail.com 5 years ago
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;
/**
*

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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…
Cancel
Save