主要使用的类有
import java.util.Random;
import javax.imageio.ImageIO;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.*;
先放完整代码
package com.bestblog.demo.unit;
import lombok.Setter;
import org.junit.Test;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Random;
/**
* @author zhouzhenyuan
*/
public class CreateCode {
/**
* 随机生成的中文关键字
*/
@Setter
private String codeElement = "今日@说法差不!多得了#你好啊我是你%这类新$建泪目*蕾姆";
/**
* 字体紧凑程度
*/
@Setter
private int compact = 30;
/**
* 字体大小设置
*/
@Setter
private int fontSize = 34;
/**
* 随机生成字体类型数组
*/
private final String[] WORD_TYPE={"宋体","微软雅黑","仿宋","黑体","幼圆","隶书","华文中宋","楷体"};
/**
* 字体颜色
*/
@Setter
private Color[] colors = {Color.BLUE,Color.CYAN,Color.CYAN,Color.GREEN,Color.red,Color.magenta,Color.yellow};
/**
* 图片宽度
*/
@Setter
private int width = 200;
/**
* 图片高度
*/
@Setter
private int height = 200;
/**
* 验证码长度
*/
@Setter
private int length = 6;
/**
* 旋转角度 【-round,round】
*/
@Setter
private int round = 10;
/**
* 绘制验证码图片 使用了GUI中的画笔工具
*/
@Test
public void createCodeImg() {
//新建一个图片缓冲区
//图片加载到缓冲区后才能进行对其进行操作
//在Java中每个RGB像素所占的位数为8 比如#FFFFFFFF 前面六位为rgb 后两位为透明度
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
File file = new File("test.jpg");
Graphics2D graphics2D = (Graphics2D) bi.getGraphics();
graphics2D.setBackground(Color.white);
graphics2D.clearRect(0, 0, width, height);
//画文本
codeText(graphics2D);
//画遮挡物
keepOut(graphics2D);
graphics2D.dispose();
try {
ImageIO.write(bi,"jpg",file);
} catch (Exception exception) {
System.err.println(exception);
}
}
//生成随机验证码 自定义字符串加数字和26个字母
public String codeText(Graphics2D graphics2D) {
StringBuilder sting = new StringBuilder();
StringBuilder stringSource = new StringBuilder(codeElement);
stringSource.append(numberWord());
Random r = new Random();
int x = 10;
for (int i = 1;i <= length;i++) {
AffineTransform transform = new AffineTransform();
//-10 到 10度 旋转
transform.rotate((r.nextInt(round*2)-round) * Math.PI / 180,x,height/2);
graphics2D.setTransform(transform);
graphics2D.setColor(colors[r.nextInt(colors.length)]);
char word = stringSource.charAt(r.nextInt(stringSource.length()));
Font font = new Font(WORD_TYPE[r.nextInt(WORD_TYPE.length)],Font.TYPE1_FONT,fontSize);
graphics2D.setFont(font);
graphics2D.drawString(String.valueOf(word),x,height/2+(r.nextInt(20)-10));
x += compact;
sting.append(word);
}
return sting.toString();
}
//该方法为验证码遮挡物
public void keepOut(Graphics2D g2) {
Random r = new Random();
for (int i = 0;i<3;i++) {
g2.setColor(colors[r.nextInt(colors.length)]);
Stroke s = new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER);
g2.setStroke(s);
Line2D lin = new Line2D.Float(r.nextInt(100), r.nextInt(100), r.nextInt(100)+100, r.nextInt(100)+100);
g2.draw(lin);
}
int x[]={r.nextInt(200),r.nextInt(200),r.nextInt(300),r.nextInt(100),r.nextInt(200),r.nextInt(200),r.nextInt(100),r.nextInt(100)};
int y[]={r.nextInt(100),r.nextInt(200),r.nextInt(100),r.nextInt(100),r.nextInt(200),r.nextInt(300),r.nextInt(100),r.nextInt(100)};
Polygon polygon2 = new Polygon(x,y,8);
g2.setColor(new Color(0x3218F659, true));
g2.fillPolygon(polygon2);
int x2[]={r.nextInt(200),r.nextInt(200),r.nextInt(200),r.nextInt(200),r.nextInt(100),r.nextInt(100),r.nextInt(100),r.nextInt(100)};
int y2[]={r.nextInt(20)+80,r.nextInt(100),r.nextInt(200),r.nextInt(200),r.nextInt(200),r.nextInt(100)-50,r.nextInt(100)+100,r.nextInt(100)-50};
Polygon polygon3 = new Polygon(x2,y2,8);
g2.setColor(new Color(0x4DF50707, true));
g2.fillPolygon(polygon3);
}
public final String numberWord() {
StringBuilder stringBuilder = new StringBuilder();
int i = 65;
int a = i;
for (;i<a+26;i++) {
stringBuilder.append((char)i);
}
a = i;
i = 97;
for (;i<a+26;i++) {
stringBuilder.append((char)i);
}
return "0123456789" + stringBuilder.toString();
}
}
验证码图片生成效果
可以躲过部分验证程序,若想更加复杂的验证码可以设置一些参数让它更加困难被识别出来