最近看了一下BufferedImage类的使用,感觉挺好玩的,BuferedImage类是Image这个抽象类的实现类,作为一个带缓冲区(Buffered,看这个单词好像就是缓冲的意思吧)图像类,主要是在内存中生成一个供图片操作的缓冲区,利用这个缓冲区我们可以很好的对图片进行描绘,缩放等操作
话不多说开始实现
/**
* 随机生成一个由大小写字母组成的长为length的字符串
*
* @param length 一个int类型数据,表示要生成的字符串长度
* @return 返回一个String类型数据,由大小写字母组成的长为length的字符串
*/
public static String createCode(int length){
String codeTemp = "";
Random rand = new Random();
for(int i = 0; i < length; i++){
//[A-Z]||[a-z](我比较懒就这样简写了,关键是大小写英文字母相差32,想到这就应该明白了)
codeTemp += (char)(97+rand.nextInt(26)-rand.nextInt(2)*32);
}
return codeTemp;
}
/**
* 根据给定字符串生成对应的验证码图片
*
* @param code 一个String类型数据,表示用于生成验证码的文本信息
*
* @param path 一个String类型数据,表示图片生成后保存的路径
* @param imageName 一个String类型数据,表示生成图片的保存名字
*/
public static void createImage(String code, String path, String imageName){
//创建一个BufferedImage对象,用来操作绘画验证码,WIDTH表示生成图片的宽,
//HEIGHT表示生成图片的高,BufferedImage.TYPE_INT_RGB表示生成图片的类型使用的是RGB的像素格式
BufferedImage buffImage = new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB);
//在有了操作的缓存区间后我们可以通过BufferedImage对象对应的Graphics对象来实现绘制
//(你可以把它看成一个画笔)
Graphics g = buffImage.getGraphics();
//设置下字体
g.setFont(new Font("宋体", Font.PLAIN, 50));
//将code,通过Graphics对象逐个绘画出
for(int i= 0; i < code.length() ; i++){
//绘制一个字符串code.subString(i, i+1),在相当于图片以左上为原点
//x为:13+i*30,y为:45 处绘画
g.drawString(code.subString(i, i+1), 13+i*30,45);
}
//好习惯,及时关闭g对象
g.dispose();
//将绘制好的BufferedImage对象保存到指定位子(图片格式是JPG)
try{
File file = new File(path, imageName + ".jpg");
ImageIO.write(buffImage , "jpeg", file);
file.createNewFile();
}
catch(Exception e){
}
}
代码写好了,我们调用下看看结果:
(。。。。。。好简洁啊,这算哪门的验证码)
public static void createImage(String code, String path, String imageName){
Random rand = new Random();
BufferedImage buffImage = new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB);
Graphics g = buffImage.getGraphics();
//将原来的Graphhics对象转为Graphics2D
//(主要是为了使用Graphics2D里的rotate方法,将文字绘画时旋转,实现东倒西歪的效果)
Graphics2D g_2D = (Graphics2D)g;
//设置绘画背景的颜色,因背景色淡一点,所以minColor值高一点130
g_2D.setColor(randomColor(130, 255));
//绘画一个填充颜色的3D效果的矩形(就是普通矩形外边多了一圈东西)
g_2D.fill3DRect(0,0,WIDTH,HEIGHT,true);
g_2D.setFont(new Font("宋体", Font.PLAIN, 50));
//控制旋转的方向,(带负号是因为负数相乘是正数,这样就能实现顺时针和逆时针交替旋转)
double rotateDir = -1;
for(int i= 0; i < code.length() ; i++){
//设置绘画字体颜色,要凸现文字所以颜色要深偏暗
g_2D.setColor(randomColor(30, 120));
/*rotate这个用的时候有点坑,比方上次旋转10度,下次旋转10度时在原先基础上再旋转10度,
一直下去字会被旋转到图片外的*/
g_2D.rotate(rand.nextInt(10)*Math.PI/180*rotateDir,13+i*30+15,20);
g_2D.drawString(code.substring(i, i+1), 13+i*30,45);
//重点,(要考,哈哈),解决rotate旋转问题
rotateDir*=-1.2;
}
//绘制20条干扰线
imageBackground(g_2D,20);
g_2D.dispose();
try{
File file = new File(path, imageName + ".jpg");
ImageIO.write(buffImage , "jpeg", file);
file.createNewFile();
}
catch(Exception e){
}
}
这个是randomColor方法(不多讲了):
/**
* 返回一个有最小范围的随机Color对象
*
* @param minColor 一个int类型数据,表示颜色最小底线
* @param minColor 一个int类型数据,表示颜色最大底线
* @return
*/
public static Color randomColor(int minColor, int maxColor ) {
//规范输入参数
if(minColor<0 || minColor > maxColor || maxColor>255) {
throw new IllegalAccessError();
}
Random rand = new Random();
return new Color(
minColor+rand.nextInt(maxColor - minColor)
,minColor+rand.nextInt(maxColor - minColor)
,minColor+rand.nextInt(maxColor - minColor)
);
}
/**
* 绘画一定数量的干扰线
* @param g_2D Graphics2D对象,明确绘画目标
* @param num 一个int类型数据,表示干扰线数
* @return 返回操作过后的Graphics2D对象
*/
public static Graphics2D imageBackground(Graphics2D g_2D, int num){
int x1,x2,y1,y2;
Random rand = new Random();
for(int i = 0; i < num; i++){
x1=rand.nextInt(WIDTH);
y1=rand.nextInt(HEIGHT);
x2=rand.nextInt(WIDTH);
y2=rand.nextInt(HEIGHT);
Color color = new Color(rand.nextInt(256),rand.nextInt(256),rand.nextInt(256));
g_2D.setColor(color);
g_2D.drawLine(x1,y1,x2,y2);
}
return g_2D;
}
下面是效果图,仔细看看矩形外边,是不是有立体效果(我看不出。。。。。)