验证码生成器(java)
本文提供一个验证码生成器,编程使用语言java。
摘要
使用该验证码生成器将会生成特定字符串的验证码图片,需指定图片高度,文字内容自适应。如果没有提供文字则自动返回文字内容及验证码图片,你也可以提供文字生成验证码图片。
代码
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Random;
/**
* 验证码生成器
* Created by chunliangh on 14-10-14.
*/
public class VerificationCoder {
public static final int _30 = 30;
public static final int _180 = 180;
public static final int DEFAULT_LINE_COUNT = 5;
public static final int DEFAULT_FONT_STYLE = Font.BOLD+Font.ITALIC;
public static final String IMG_TYPE = "jpg";
//200个常用汉字
private static final char[] codeArray = new char[]{'的','我','美','张','爱','完','天','地','高','啊',
'鹅','丽','雨','网','牛','春','秋','刚','成','公','晶','亮','国','路','眼','手','他','你','钱','元',
'日','风','水','妈','爸','浩','开','米','无','韩','丹','佳','家','云','杨','北','西','东','男','和',
'亚','放','林','刘','正','指','智','景','黄','在','服','陈','道','味','大','静','为','李','雪','学',
'虎','图','旁','领','瘦','胖','左','有','游','玉','社','见','步','近','问','同','电','雷','周','宇',
'高','老','是','冰','泪','用','接','出','会','来','小','打','答','得','等','多','都','平','票','拍',
'纱','说','上','下','个','给','跟','话','就','叫','那','年','能','买','们','没','量','里','了','均',
'把','被','表','比','才','从','吃','次','差','想','恶','晚','前','走','最','做','中','这','些','写',
'热','如','然','要','新','求','修','定','明','毛','世','选','霞','艳','朋','录','敏','民','雅','猫',
'界','棒','旅','行','程','英','带','达','客','本','望','品','礼','绿','迪','姐','唱','场','还','边',
'记','评','盼','钟','郭','经','祝','福','龙','孩'};
/**
* 生成验证码字符串及对应图片的字节数组(使用自适应的宽度、默认的样式及默认的干扰线数量)
* @param height 图片高度
* @param count 验证码字数
* @return [String:验证码字符串,byte[]:验证码图片字节数组]
*/
public static Object[] verificationCodeAndImg(int height,int count){
char[] codes = generateCodes(count);
return new Object[]{new String(codes),verificationCodeImg(height,codes)};
}
/**
* 生成验证码字符串及对应图片的字节数组
* @param width 预生成验证码图片宽度
* @param height 预生成验证码图片高度
* @param count 给定的验证码字符数
* @param fontStyle 图片中文字的样式
* @param lineCount 干扰线的数量
* @return [String:验证码字符串,byte[]:验证码图片字节数组]
*/
public static Object[] verificationCodeAndImg(int width,int height,int count,int fontStyle,int lineCount){
char[] codes = generateCodes(count);
return new Object[]{new String(codes),verificationCodeImg(width,height,codes,fontStyle,lineCount)};
}
/**
* 生成验证码字符串对应图片的字节数组(使用自适应的宽度、默认的样式及默认的干扰线数量)
* @param height 图片高度
* @param codes 验证码字符数组
* @return byte[]:验证码图片字节数组
*/
public static byte[] verificationCodeImg(int height,char[] codes){
return verificationCodeImg(0,height,codes,DEFAULT_FONT_STYLE,DEFAULT_LINE_COUNT);
}
/**
* 生成验证码字符串对应图片的字节数组
* @param width 预生成验证码图片宽度
* @param height 预生成验证码图片高度
* @param codes 给定的验证码字符数组
* @param fontStyle 图片中文字的样式
* @param lineCount 干扰线的数量
* @return byte[]:验证码图片字节数组
*/
public static byte[] verificationCodeImg(int width,int height,char[] codes,int fontStyle,int lineCount){
//处理宽度
int suitWidth = height*codes.length;
if (width<suitWidth) width = suitWidth;
BufferedImage bi = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
Graphics g = bi.getGraphics();
setBackgroundColor(g,width,height);
addBackGroundLine(g,width,height,lineCount);
addCodes(g,height,codes,fontStyle);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ImageIO.write(bi, IMG_TYPE, bos);
return bos.toByteArray();
} catch (IOException e) {}
return null;
}
//设置背景色
private static void setBackgroundColor(Graphics g,int width,int height){
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
}
//设置边框颜色
private static void setRectColor(Graphics g,int width,int height){
g.setColor(Color.BLUE);
g.drawRect(0, 0, width-1, height-1);
}
//画干扰线
private static void addBackGroundLine(Graphics g,int width,int height,int lineCount){
for (int i = 0; i < lineCount; i++) {// 设置线条个数并画线
if (i%2==0){
g.setColor(Color.BLACK);
}else{
g.setColor(Color.RED);
}
int x1 = new Random().nextInt(width);
int y1 = new Random().nextInt(height);
int x2 = new Random().nextInt(width);
int y2 = new Random().nextInt(height);
g.drawLine(x1, y1, x2, y2);
}
}
//填充汉字
private static void addCodes(Graphics g,int height,char[] codes,int fontStyle){
//字号:=height*Math.sqrt(3)/(1+Math.sqrt(3))=height*0.634
int size = (int) (height*0.634);
int _x = size/2; //字的横坐标相对圆心横坐标的偏移量
int y0 = (height+size)/2;//字的纵坐标
int x = height/2,y = x; //圆心的横纵坐标
Graphics2D g2D = (Graphics2D) g;
g2D.setFont(new Font(null, fontStyle, size));
for (int i=0,len=codes.length;i<len;i++){
if (i%2==0){
g2D.setColor(Color.BLACK);
}else{
g2D.setColor(Color.RED);
}
int degree = new Random().nextInt() % _30;//随机生成偏转角度
g2D.rotate(degree * Math.PI/_180, x, y);//正向偏转
g2D.drawString(codes[i] + "", x-_x, y0);//添加字符
g2D.rotate(-degree * Math.PI/_180, x, y);//负向偏转
x += height;
}
}
//给定长度生成随机字符数组
private static char[] generateCodes(int count) {
char[] res = new char[count];
for (int i=0,len=codeArray.length;i<count;i++){
int j = new Random().nextInt(len);
res[i] = codeArray[j];
}
return res;
}
//测试
public static void main(String[] args){
Object[] res = verificationCodeAndImg(30,2);
System.out.println(res[0]);
try {
BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream((byte[]) res[1]));
ImageIO.write(bufferedImage,IMG_TYPE,new File("/Users/daojian/Desktop/ass.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
浙公网安备 33010602011771号