比尔云BierYun--阿里云最新优惠活动
阿里云优惠码丨阿里云代金券

Java的生成图片验证码(有点仿QQ验证码的意思)

Java的生成图片验证码(有点仿QQ验证码的意思)http://www.bieryun.com/806.html

看了挺多图片验证码的代码,感觉没什么长的好看点的,就自己动手写了个,写完发现跟QQ的有几分相似,比较满意。

功能包括:自定义图片尺寸和字符长度,随机背景颜色和字符颜色,随机字符偏移角度,字符平滑边缘,干扰线,噪点,背景扭曲。

本来想做字符扭曲的,不知道怎的先生成文字再扭曲就报错了,先就这样吧,希望有高手能帮助修正一下。

需要说明的是之所以有几分像QQ的验证码感觉是因为这个阿尔及利亚的字体,如果系统没有的话需要自行安装,百度搜字体名能下载到,丢系统字体文件夹就行。

JAVA文件和字体打了个包发资里里,http://download.csdn.net/detail/ruixue0117/7138469。

效果图:

AuthImage类:

[java] 查看纯文本

  1.  hh.com.util;
  2. import  java.io.IOException;
  3. import  javax.servlet.ServletException;
  4. import  javax.servlet.http.HttpServletRequest;
  5. import  javax.servlet.http.HttpServletResponse;
  6. import  javax.servlet.http.HttpSession;
  7. 公共 AuthImage  扩展 javax.servlet.http.HttpServlet  实现 javax.servlet.Servlet {
  8.     static final long  serialVersionUID = 1L;
  9.     公共无效 服务(HttpServletRequest请求,HttpServletResponse响应)  抛出 ServletException,IOException {
  10.         response.setHeader(“Pragma” ,  “No-cache” );
  11.         response.setHeader(“Cache-Control” ,  “no-cache” );
  12.         response.setDateHeader(“Expires” ,  0 );
  13.         response.setContentType(“image / jpeg” );
  14.         //生成随机字串
  15.         字符串verifyCode = VerifyCodeUtils.generateVerifyCode(4 );
  16.         //存入会话的会话
  17.         HttpSession session = request.getSession(true );
  18.         session.setAttribute(“rand” ,verifyCode.toLowerCase());
  19.         //生成图片
  20.         int  w =  200 ,h =  80 ;
  21.         VerifyCodeUtils.outputImage(w,h,response.getOutputStream(),verifyCode);
  22.     }
  23. }

 

VerifyCodeUtils类,生成图片流,然后不同框架下的输出可以参考上面的代码或者自行百度,无非就是获取的OutputStream和ContentType的的区别,主要的方法可直接执行:

(PS:不想下载的话复制这个类就行了)

[java] 查看纯文本

  1.  hh.com.util;
  2. import  java.awt.Color;
  3. import  java.awt.Font;
  4. import  java.awt.Graphics;
  5. import  java.awt.Graphics2D;
  6. import  java.awt.LinearGradientPaint;
  7. import  java.awt.Paint;
  8. import  java.awt.RenderingHints;
  9. import  java.awt.geom.AffineTransform;
  10. import  java.awt.image.BufferedImage;
  11. import  java.io.File;
  12. import  java.io.FileOutputStream;
  13. import  java.io.IOException;
  14. import  java.io.OutputStream;
  15. import  java.util.Arrays;
  16. import  java.util.Random;
  17. import  javax.imageio.ImageIO;
  18. 公共 VerifyCodeUtils {
  19.     //使用到阿尔及利亚字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,I,O几个容易混淆的字符
  20.     public static final  String VERIFY_CODES = 23456789ABCDEFGHJKLMNPQRSTUVWXYZ  ;
  21.     private static  Random =  new  Random();
  22.     / **
  23.      *使用系统默认字符源生成验证码
  24.      * @param verifySize验证码长度
  25.      * @返回
  26.      * /
  27.     public static  String generateVerifyCode(int  verifySize){
  28.         返回 generateVerifyCode(verifySize,VERIFY_CODES);
  29.     }
  30.     / **
  31.      *使用指定源生成验证码
  32.      * @param verifySize验证码长度
  33.      * @param来源验证码字符源
  34.      * @返回
  35.      * /
  36.     公共静态 字符串generateVerifyCode(诠释 verifySize,字符串来源){
  37.         if (sources ==  null  || sources.length()==  0 ){
  38.             来源= VERIFY_CODES;
  39.         }
  40.         int  codesLen = sources.length();
  41.         随机rand =   随机(System.currentTimeMillis());
  42.         StringBuilder verifyCode =  new  StringBuilder(verifySize);
  43.         for int  i =  0 ; i <verifySize; i ++){
  44.             verifyCode.append(sources.charAt(rand.nextInt(codesLen- 1 )));
  45.         }
  46.         返回 verifyCode.toString();
  47.     }
  48.     / **
  49.      *生成随机验证码文件,并返回验证码值
  50.      * @param w
  51.      * @参数h
  52.      * @param outputFile
  53.      * @param verifySize
  54.      * @返回
  55.      * @抛出IOException
  56.      * /
  57.     public static  String outputVerifyImage(int  w,  int  h,File outputFile,  int  verifySize)  throws IOException {
  58.         String verifyCode = generateVerifyCode(verifySize);
  59.         outputImage(w,h,outputFile,verifyCode);
  60.         返回 verifyCode;
  61.     }
  62.     / **
  63.      *输出随机验证码图片流,并返回验证码值
  64.      * @param w
  65.      * @参数h
  66.      * @参数操作系统
  67.      * @param verifySize
  68.      * @返回
  69.      * @抛出IOException
  70.      * /
  71.     public static  String outputVerifyImage(int  w,  int  h,OutputStream os,  int  verifySize)  throws IOException {
  72.         String verifyCode = generateVerifyCode(verifySize);
  73.         outputImage(w,h,os,verifyCode);
  74.         返回 verifyCode;
  75.     }
  76.     / **
  77.      *生成指定验证码图像文件
  78.      * @param w
  79.      * @参数h
  80.      * @param outputFile
  81.      * @参数代码
  82.      * @抛出IOException
  83.      * /
  84.     public static void  outputImage(int  w,  int  h,File outputFile,String code)  throws  IOException {
  85.         if (outputFile ==  null ){
  86.             返回;
  87.         }
  88.         文件dir = outputFile.getParentFile();
  89.         if (!dir.exists()){
  90.             dir.mkdirs();
  91.         }
  92.         尝试{
  93.             outputFile.createNewFile();
  94.             FileOutputStream fos =  new  FileOutputStream(outputFile);
  95.             outputImage(w,h,fos,code);
  96.             fos.close();
  97.         }  捕捉(IOException的发送){
  98.              e;
  99.         }
  100.     }
  101.     / **
  102.      *输出指定验证码图片流
  103.      * @param w
  104.      * @参数h
  105.      * @参数操作系统
  106.      * @参数代码
  107.      * @抛出IOException
  108.      * /
  109.     public static void  outputImage(int  w,  int  h,OutputStream os,String code)  throws  IOException {
  110.         int  verifySize = code.length();
  111.         BufferedImage image =  new  BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
  112.         随机rand =   随机();
  113.         Graphics2D g2 = image.createGraphics();
  114.         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
  115.         颜色[]颜色=   颜色[ 5 ];
  116.         颜色[] colorSpaces =   颜色[] {Color.WHITE,Color.CYAN,
  117.                 Color.GRAY,Color.LIGHT_GRAY,Color.MAGENTA,Color.ORANGE,
  118.                 Color.PINK,Color.YELLOW};
  119.         float [] fractions =  new float [colors.length];
  120.         for int  i =  0 ; i <colors.length; i ++){
  121.             colors [i] = colorSpaces [rand.nextInt(colorSpaces.length)];
  122.             分数[i] = rand.nextFloat();
  123.         }
  124.         Arrays.sort(级分);
  125.         g2.setColor(Color.GRAY); //设置边框色
  126.         g2.fillRect(0 ,  0 ,W,H);
  127.         颜色C = getRandColor(200 ,  250 );
  128.         g2.setColor(C); //设置背景色
  129.         g2.fillRect(0 ,  2 ,W,H- 4 );
  130.         //绘制干扰线
  131.         随机随机=   随机();
  132.         g2.setColor(getRandColor(160 ,  200 )); //设置线条的颜色
  133.         for  (int  i =  0 ; i <  20 ; i ++){
  134.             int  x = random.nextInt(w –  1 );
  135.             int  y = random.nextInt(h –  1 );
  136.             int  xl = random.nextInt(6 )+  1 ;
  137.             int  yl = random.nextInt(12 )+  1 ;
  138.             g2.drawLine(x,y,x + xl +  40 ,y + yl +  20 );
  139.         }
  140.         //添加噪点
  141.         float  yawpRate =  0 .05f; //噪声率
  142.         int  area =(int )(yawpRate * w * h);
  143.         for  (int  i =  0 ; i <area; i ++){
  144.             int  x = random.nextInt(w);
  145.             int  y = random.nextInt(h);
  146.             int  rgb = getRandomIntColor();
  147.             image.setRGB(x,y,rgb);
  148.         }
  149.         剪切(g2,w,h,c); //使图片扭曲
  150.         g2.setColor(getRandColor(100 ,  160 ));
  151.         int  fontSize = h- 4 ;
  152.         Font font =  new  Font(“Algerian” ,Font.ITALIC,fontSize);
  153.         g2.setFont(字体);
  154.         char [] chars = code.toCharArray();
  155.         for int  i =  0 ; i <verifySize; i ++){
  156.             AffineTransform affine =  new  AffineTransform();
  157.             affine.setToRotation(Math.PI /  4  * rand.nextDouble()*(rand.nextBoolean()?  1  :-1 ),(w / verifySize)* i + fontSize / 2 ,h / 2 );
  158.             g2.setTransform(仿射);
  159.             g2.drawChars(字符,I,  1 ,((W- 10 )/ verifySize)* I +  5 ,H / 2  + fontSize的/ 2  –  10 );
  160.         }
  161.         g2.dispose();
  162.         ImageIO.write(image,  “jpg” ,os);
  163.     }
  164.     private static  Color getRandColor(int  fc,  int  bc){
  165.         如果 (fc>  255
  166.             fc =  255 ;
  167.         如果 (bc>  255
  168.             bc =  255 ;
  169.         int  r = fc + random.nextInt(bc – fc);
  170.         int  g = fc + random.nextInt(bc – fc);
  171.         int  b = fc + random.nextInt(bc – fc);
  172.         返回新的 颜色(r,g,b);
  173.     }
  174.     private static int  getRandomIntColor(){
  175.         int [] rgb = getRandomRgb();
  176.         int  color =  0 ;
  177.         for  (int  c:rgb){
  178.             颜色=颜色<<  8 ;
  179.             color = color | C;
  180.         }
  181.         返回 颜色;
  182.     }
  183.     private static int [] getRandomRgb(){
  184.         int [] rgb =  new int [ 3 ];
  185.         for  (int  i =  0 ; i <  3 ; i ++){
  186.             rgb [i] = random.nextInt(255 );
  187.         }
  188.         返回 rgb;
  189.     }
  190.     private static void  shear(Graphics g,  int  w1,  int  h1,Color color){
  191.         剪切X(g,w1,h1,颜色);
  192.         剪切Y(g,w1,h1,颜色);
  193.     }
  194.     private static void  shearX(Graphics g,  int  w1,  int  h1,Color color){
  195.         int  period = random.nextInt(2 );
  196.         boolean  borderGap =  true ;
  197.         int  frames =  1 ;
  198.         int  phase = random.nextInt(2 );
  199.         for  (int  i =  0 ; i <h1; i ++){
  200.              d =()(期间>>  1
  201.                     * Math.sin(()我/()期间
  202.                             +(6 .2831853071795862D *()相)
  203.                             /()帧);
  204.             g.copyArea(0 ,I,W1,  1 ,(INT )d,  0 );
  205.             if  (borderGap){
  206.                 g.setColor(颜色);
  207.                 g.drawLine((int )d,i,  0 ,i);
  208.                 g.drawLine((int )d + w1,i,w1,i);
  209.             }
  210.         }
  211.     }
  212.     private static void  shearY(Graphics g,  int  w1,  int  h1,Color color){
  213.         int  period = random.nextInt(40 )+  10 // 50;
  214.         boolean  borderGap =  true ;
  215.         int  frames =  20 ;
  216.         int  phase =  7 ;
  217.         for  (int  i =  0 ; i <w1; i ++){
  218.              d =()(期间>>  1
  219.                     * Math.sin(()我/()期间
  220.                             +(6 .2831853071795862D *()相)
  221.                             /()帧);
  222.             g.copyArea(I,  0 ,  1 ,H1,  0 ,(INT )d);
  223.             if  (borderGap){
  224.                 g.setColor(颜色);
  225.                 g.drawLine(i,(int )d,i,  0 );
  226.                 g.drawLine(i,(int )d + h1,i,h1);
  227.             }
  228.         }
  229.     }
  230.     public static void  main(String [] args)  throws  IOException {
  231.         文件dir =   文件(“F:/ verifies” );
  232.         int  w =  200 ,h =  80 ;
  233.         for int  i =  0 ; i <  50 ; i ++){
  234.             String verifyCode = generateVerifyCode(4 );
  235.             File file =  new  File(dir,verifyCode +  “.jpg” );
  236.             outputImage(w,h,file,verifyCode);
  237.         }
  238.     }
  239. }

web.xml中配置:

[html] 查看纯文本

  1. < servlet >
  2.     < servlet-name > AuthImage </ servlet-name >
  3.     < servlet-class > hh.com.util.AuthImage </ servlet-class >
  4.     </ servlet >
  5.     < servlet-mapping >
  6.     < servlet-name > AuthImage </ servlet-name >
  7.     < url-pattern > / authImage </ url-pattern >
  8.     </ servlet-mapping >
未经允许不得转载:比尔云 » Java的生成图片验证码(有点仿QQ验证码的意思)
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

强烈推荐

高性能SSD云服务器ECS抗攻击,高可用云数据库RDS