BufferedImage使用----生成一张验证码图片

BufferedImage----生成一张验证码图片

最近看了一下BufferedImage类的使用,感觉挺好玩的,BuferedImage类是Image这个抽象类的实现类,作为一个带缓冲区(Buffered,看这个单词好像就是缓冲的意思吧)图像类,主要是在内存中生成一个供图片操作的缓冲区,利用这个缓冲区我们可以很好的对图片进行描绘,缩放等操作

话不多说开始实现

  1. 在绘画验证码图片之前我们需要一个String类型的随机字符串来作为验证码图片的文字信息,这里用到了Random类来实现字符串的随机生成
/**
	 * 随机生成一个由大小写字母组成的长为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;
	}
  1. 随机字符串有了,那开始通过BufferedImage对象绘画图象
/**
	 * 根据给定字符串生成对应的验证码图片
	 * 
	 * @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){}	
	}
	

代码写好了,我们调用下看看结果:
在这里插入图片描述
(。。。。。。好简洁啊,这算哪门的验证码)

  1. 本来不想写了,但想想还是来点吧,常见的验证码首先有背景色吧,文字颜色也不相同吧,是不是文字还不是整齐排的(东倒西歪的),来,代码跟上:
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;
	}

下面是效果图,仔细看看矩形外边,是不是有立体效果(我看不出。。。。。)

(不带干扰线的):
不带干扰线的
(带干扰线的)
带干扰线的

发布了6 篇原创文章 · 获赞 15 · 访问量 2048

猜你喜欢

转载自blog.csdn.net/LioTomcat/article/details/104516562