java验证码背景如何构造及最终生成

前面讲到了验证码中的数字、字母和汉字的随机生成,但是验证码中肯定不仅仅是包含了这些东西啊。大家可以看到数字啊什么的是斜的,或者背景颜色是五颜六色的甚至各种线条都有。那么,这些东西该怎么实现呢?

1、背景颜色随机输出的实现,直接给代码吧- -

public Color getRandColor(int lower,int upper){ 

  Random random = new Random(); 

  if(upper>255) 

   upper=255; 

  if(upper<1) 

   upper=1; 

  if(lower<1) 

   lower=1; 

  if(lower>255) 

   lower=255; 

  int r=lower+random.nextInt(upper-lower); 

  int g=lower+random.nextInt(upper-lower); 

  int b=lower+random.nextInt(upper-lower); 

  return new Color(r,g,b); 

2、随机绘制干扰线和干扰点- -

// 随机产生5条干扰线,使图象中的认证码不易被其它程序探测到 

  for(int i=0;i<5;i++){ 

   int x=random.nextInt(width); 

   int y=random.nextInt(height); 

   int x1=random.nextInt(width); 

   int y1=random.nextInt(height); 

   g.drawLine(x, y, x1, y1); 

  } 

  //随机产生100个点,使图中认证码不易被其它程序探测到(线的起点和终点一样就是成一个点了)

  for(int i=0;i<100;i++){ 

  int x=random.nextInt(width); 

  int y=random.nextInt(height);  

  g.drawLine(x, y, x, y); 

 }

3、图片的旋转与缩放,java.awt.geom.AffineTransform类用来实现这些功能

AffineTransform trans=new AffineTransform();

trans.scale(1.1,1.3);//用scale方法对图片进行x轴1.1倍,y轴1.3倍的放大。

trans.rotate(30*3.14/180,20,7);//用rotate方法以(20,7)为轴点对图片进行30个弧度的变换。

那怎么把这些效果放进图片里面呢?毕竟AffineTransform类创建出来的不是一个图片对象啊?

Graphics g=image.getGraphics(); //创建一个图形类

Graphics2D g2d=(Graphics2D)g;//创建一个Graphics2D对象,如果缩放图片就用到,否则不需要。

g2d.setTransform(trans);//缩放成功


整一个验证码实现代码如下:

package com.servlet; 

import java.awt.Color; 

import java.awt.Font; 

import java.awt.Graphics; 

import java.awt.image.BufferedImage; 

import java.io.IOException; 

import java.util.Random; 

import javax.imageio.ImageIO; 

import javax.servlet.ServletException; 

import javax.servlet.ServletOutputStream; 

import javax.servlet.http.HttpServlet; 

import javax.servlet.http.HttpServletRequest; 

import javax.servlet.http.HttpServletResponse; 

import javax.servlet.http.HttpSession;


public class ImageServlet extends HttpServlet { 

public void doGet(HttpServletRequest request, HttpServletResponse response) 

   throws ServletException, IOException { 

            doPost(request, response); 

public void doPost(HttpServletRequest request, HttpServletResponse response) 

   throws ServletException, IOException { 

  int width=150;//验证码图片宽度 

  int height=60;//验证码图片高度 

  BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); 

  Graphics g=image.getGraphics(); //创建一个图形类

  Random random=new Random();//创建一个随机类 

  g.setColor(getRandColor(200,250));//背景颜色要偏淡 

  g.fillRect(0, 0, width, height);//画背景 

  g.setColor(getRandColor(0,255));//边框颜色 

        g.drawRect(0, 0, width-1, height-1);//画边框 

 // 随机产生5条干扰线,使图象中的认证码不易被其它程序探测到 

  for(int i=0;i<5;i++){ 

   int x=random.nextInt(width); 

   int y=random.nextInt(height); 

   int x1=random.nextInt(width); 

   int y1=random.nextInt(height); 

   g.drawLine(x, y, x1, y1); 

  } 

  //随机产生100个点,使图中认证码不易被其它程序探测到(线的起点和终点一样就是成一个点了)

  for(int i=0;i<100;i++){ 

  int x=random.nextInt(width); 

  int y=random.nextInt(height);  

  g.drawLine(x, y, x, y); 

 }

  g.setColor(getRandColor(160,200));

        Font font = new Font("Times New Roman", Font.ITALIC,38);  // 创建字体,字体的大小应该根据图片的高度来定。 

        g.setFont(font);//设置字体 

        int length = 6;  // 设置默认生成6个验证码 

  String s="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; // 设置备选验证码:包括"a-z"和数字"0-9" 

  String sRand=""; 

     

        // 用随机产生的颜色将验证码绘制到图像中。 

        // 生成随机颜色(因为是做前景,所以偏深)   

        //调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成 

        g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));   

  for(int i=0;i<length;i++){ 

   String ch=String .valueOf(s.charAt(random.nextInt(s.length()))); 

   sRand+=ch; 

   g.drawString(ch, 22*i+12, (random.nextInt(5)-2)*i+40); 

   //drawString(a,x,y)a为要画出来的东西,x和y表示要画的东西最左侧字符的基线位于此图形上下文坐标系的 (x, y) 位置处

  } 

  //将生成的字符串存储在session中 

  HttpSession session=request.getSession();   

  session.setAttribute("checkCode", sRand); 

  g.dispose();//图像生效 

  //禁止图像缓存 

  response.setHeader("Pragma", "No-cache"); 

  response.setHeader("Cache-Control", "no-cache"); 

  response.setDateHeader("Expires", 0);   

  response.setContentType("image/jpeg"); 

  //创建二进制的输出流 

  ServletOutputStream sos=response.getOutputStream(); 

        // 将图像输出到Servlet输出流中。 

        ImageIO.write(image, "jpeg", sos); 

        sos.flush(); 

        sos.close(); 

}


public Color getRandColor(int lower,int upper){ 

  Random random = new Random(); 

  if(upper>255) 

   upper=255; 

  if(upper<1) 

   upper=1; 

  if(lower<1) 

   lower=1; 

  if(lower>255) 

   lower=255; 

  int r=lower+random.nextInt(upper-lower); 

  int g=lower+random.nextInt(upper-lower); 

  int b=lower+random.nextInt(upper-lower); 

  return new Color(r,g,b); 

}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值