J2EE验证码图片如何生成和点击刷新验证码

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.fullgoal.ip.config;  
  2.   
  3. import java.awt.Color;  
  4. import java.awt.Font;  
  5. import java.awt.Graphics;  
  6. import java.awt.Image;  
  7. import java.awt.image.BufferedImage;  
  8. import java.io.ByteArrayOutputStream;  
  9. import java.io.IOException;  
  10. import java.io.OutputStream;  
  11. import java.util.Random;  
  12.   
  13. import javax.imageio.ImageIO;  
  14. import javax.servlet.ServletException;  
  15. import javax.servlet.http.HttpServletRequest;  
  16. import javax.servlet.http.HttpServletResponse;  
  17. import javax.servlet.http.HttpSession;  
  18. /* 验证码图片生成步骤  
  19. 创建BufferedImage对象。  
  20. 获取BufferedImage的画笔,即调用getGraphics()方法获取Graphics对象。  
  21. 调用Graphics对象的setColor()方法和fillRect()方法设置图片背景颜色。  
  22. 调用Graphics对象的setColor()方法和drawLine()方法设置图片干扰线。  
  23. 调用BufferedImaged对象的setRGB()方法设置图片的噪点。  
  24. 调用Graphics对象的setColor()方法、setFont()方法和drawString()方法设置图片验证码。  
  25. 因为验证码的图片的宽度和高度要根据网站的风格来确定的,所以字体的大小需要根据图片的宽度和高度来确定,用到了小小的技巧。  
  26.  */  
  27. public class Verification {  
  28.   private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";  
  29.     
  30.   /**  
  31.    * 生成一个宽为width, 高为height, 验证码为vcode的图片  
  32.    * @param width 图片的宽  
  33.    * @param height 图片的高  
  34.    * @param vcode 验证码字符串  
  35.    * @return 返回图片验证码  
  36.    */  
  37.   public static BufferedImage getImage(int width, int height, String vvcode){  
  38.     return getImage(width, height, vvcode, 20);  
  39.   }  
  40.   /**  
  41.    * 生成一个宽为width, 高为height, 验证码为vvcode的图片,图片中干扰线的条数为lineCnt  
  42.    * @param width 图片的宽  
  43.    * @param height 图片的高  
  44.    * @param vvcode 验证码字符串  
  45.    * @param lineCnt 干扰线的条数,建议为10条左右,可根据结果适当调整  
  46.    * @return 返回图片验证码  
  47.    */  
  48.   public static BufferedImage getImage(int width, int height, String vvcode, int lineCnt){  
  49.     return createImage(width, height, vvcode, lineCnt, 0.01);  
  50.   }  
  51.   /**  
  52.    * 生成一个宽为width, 高为height, 验证码为vvcode的图片,图片中干扰线的条数为lineCnt  
  53.    * 噪声比为noiseRate,即图片中噪音像素点的百分比  
  54.    * @param width 图片的宽  
  55.    * @param height 图片的高  
  56.    * @param vvcode 验证码字符串  
  57.    * @param lineCnt 干扰线的条数,建议为10条左右,可根据结果适当调整  
  58.    * @param noiseRate 图片中噪音像素点占总像素的百分比  
  59.    * @return 返回图片验证码  
  60.    */  
  61.   public static BufferedImage getImage(int width, int height, String vvcode, int lineCnt, double noiseRate){  
  62.     return createImage(width, height, vvcode, lineCnt, noiseRate);  
  63.   }  
  64.     
  65.   /**  
  66.    *   
  67.    * 生成一个宽为width, 高为height, 验证码为vvcode的图片,图片中干扰线的条数为lineCnt  
  68.    * 噪声比为noiseRate,即图片中噪音像素点的百分比  
  69.    * @param width 图片的宽  
  70.    * @param height 图片的高  
  71.    * @param vvcode 验证码字符串  
  72.    * @param lineCnt 干扰线的条数,建议为10条左右,可根据结果适当调整  
  73.    * @param noiseRate 图片中噪音像素点占总像素的百分比  
  74.    * @return 返回图片验证码  
  75.    */  
  76.   private static BufferedImage createImage(int width, int height, String vvcode, int lineCnt, double noiseRate){  
  77.     int fontWidth = ((int)(width * 0.8)) / vvcode.length();  
  78.     int fontHeight = (int)(height * 0.7);  
  79.     //为了在任意的width和height下都能生成良好的验证码,  
  80.     //字体的大小为fontWdith何fontHeight中的小者,  
  81.     int fontSize = Math.min(fontWidth, fontHeight);  
  82.     //drawString时要用到  
  83.     int paddingX = (int) (width * 0.1);  
  84.     int paddingY = height - (height - fontSize) / 2;  
  85.       
  86.     //创建图像  
  87.     BufferedImage buffimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
  88.     //获得画笔  
  89.     Graphics g = buffimg.getGraphics();  
  90.     //设置画笔的颜色  
  91.     g.setColor(getRandColor(200, 255));  
  92.     //然后填充一个矩形,即设置背景色  
  93.     g.fillRect(0, 0, width, height);  
  94.       
  95.     // 设置干扰线  
  96.     for (int i = 0; i < lineCnt; i++) {  
  97.         //随机获取干扰线的起点和终点  
  98.       int xs = (int)(Math.random() * width);  
  99.       int ys = (int)(Math.random() * height);  
  100.       int xe = (int)(Math.random() * width);  
  101.       int ye = (int)(Math.random() * height);  
  102.       g.setColor(getRandColor(1, 255));  
  103.       g.drawLine(xs, ys, xe, ye);  
  104.     }  
  105.     // 添加噪点  
  106.     int area = (int) (noiseRate * width * height);  
  107.     for(int i=0; i<area; ++i){  
  108.         int x = (int)(Math.random() * width);  
  109.         int y = (int)(Math.random() * height);  
  110.         buffimg.setRGB(x, y, (int)(Math.random() * 255));  
  111.     }  
  112.     //设置字体  
  113.     Font font = new Font("Ravie", Font.PLAIN, fontSize);  
  114.     g.setFont(font);  
  115.       
  116.     for(int i=0; i<vvcode.length(); ++i){  
  117.         String ch = vvcode.substring(i, i+1);  
  118.         g.setColor(getRandColor(1, 199));  
  119.         g.drawString(ch, paddingX + fontWidth * i, paddingY);  
  120.     }  
  121.     return buffimg;  
  122.       
  123.   }  
  124.   /**  
  125.    * 获取随机的颜色,r,g,b的取值在L到R之间  
  126.    * @param L 左区间  
  127.    * @param R 右区间  
  128.    * @return 返回随机颜色值  
  129.    */  
  130.   private static Color getRandColor(int L, int R){  
  131.     if(L > 255)  
  132.       L = 255;  
  133.     if(R > 255)  
  134.       R = 255;  
  135.     if(L < 0)  
  136.       L = 0;  
  137.     if(R < 0)  
  138.       R = 0;  
  139.     int interval = R - L;   
  140.     int r = L + (int)(Math.random() * interval);  
  141.     int g = L + (int)(Math.random() * interval);  
  142.     int b = L + (int)(Math.random() * interval);  
  143.     return new Color(r, g, b);  
  144.   }  
  145.   
  146.   /**  
  147.    * 随机生成若干个由大小写字母和数字组成的字符串  
  148.    * @param len 随机生成len个字符  
  149.    * @return 返回随机生成的若干个由大小写字母和数字组成的字符串  
  150.    */  
  151.   public static String getRandvvcode(int len){  
  152.     String vvcode = "";  
  153.     for(int i=0; i<len; ++i){  
  154.       int index = (int)(Math.random() * ALPHABET.length());  
  155.       vvcode = vvcode + ALPHABET.charAt(index);  
  156.     }  
  157.     return vvcode;  
  158.   }  
  159.   /**  
  160.    * 将图片转为byte数组  
  161.    * @param image 图片  
  162.    * @return 返回byte数组  
  163.    * @throws IOException  
  164.    */  
  165.   public static byte[] getByteArray(BufferedImage image) throws IOException{  
  166.     ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  167.     ImageIO.write(image, "png", baos);  
  168.     return baos.toByteArray();  
  169.     //ByteArrayOutputStream 不需要close  
  170.       
  171.   }  
  172.   
  173.   
  174. //使用验证码图片  
  175. //在verificationvvcode.java这个servlet中调用上面的类生成验证码图片,然后将图片返回给客户端。  
  176. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  177.     HttpSession session = request.getSession();  
  178.     //随机生成字符串,并写入session  
  179.     String vcode = Verification.getRandvvcode(4);  
  180.     session.setAttribute("verification", vcode);  
  181.     BufferedImage image = com.fullgoal.ip.config.Verification.getImage(100,30, vcode, 5);  
  182.     response.setContentType("image/png");  
  183.     OutputStream out = response.getOutputStream();  
  184.     //com.fullgoal.ip.config.Verification为包名  
  185.     out.write(com.fullgoal.ip.config.Verification.getByteArray(image));  
  186.     out.flush();  
  187.     out.close();  
  188.       
  189.   }  
  190. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值