java图片验证码包括文字和图片的旋转

本文介绍了一种使用Java生成包含加减运算的文字图片验证码的方法。通过随机选择数字和运算符,生成带有旋转效果的验证码图片,并添加干扰点和线条提高安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



java图片验证码包括文字图片的旋转:

此例子演示的是两位数的加减运算,需要的可以通过自己的修改获得更多的方式:

    package com.utils;  
      
    import java.awt.Color;  
    import java.awt.Font;  
    import java.awt.Graphics;  
    import java.awt.Graphics2D;  
    import java.awt.RenderingHints;  
    import java.awt.image.BufferedImage;  
    import java.util.Random;  
      
    import javax.swing.ImageIcon;  
    import javax.swing.JFrame;  
    import javax.swing.JLabel;  
      
    public class VerificationCode {  
      
        private int result2=0;  
        Random rand = new Random();  
        /** 
         * 随机产生的加数和被加数 
         */  
        private int jiashu=0;  
        private int beijiashu=0;  
        /** 
         * 随机产生的计算方式,0表示加,1表示减 
         */  
        private int js=0;    
        private char[] aa={'零','壹','贰','叁','肆','伍','陆','柒','捌','玖'};  
        private char[] bb={'0','1','2','3','4','5','6','7','8','9'};  
        private char[] cc={'〇','一','二','三','四','五','六','七','八','九'};  
        private char[] action={'加','减','+','-'};  
        private char[] jieguo={'等','是'};  
        public static void main(String[] args) {  
            // TODO Auto-generated method stub  
            VerificationImage code=new VerificationImage();  
             JFrame jFrame=new JFrame();  
              jFrame.setBounds(400, 400, 250, 250);  
                
              ImageIcon img = new ImageIcon(code.getVerificationCode2());   
              JLabel background = new JLabel(img);  
                
              jFrame.add(background);  
              jFrame.setVisible(true);  
              jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
        }  
        /** 
         * 第二种验证码的计算方式,两位数的加减法 
         * @return 一个新的验证码图片 
         */  
        public BufferedImage getVerificationCode2()  
        {  
            int width=150;  
            int height=70;  
            int degree=0;//继续一共旋转的角度,方便最后的时候旋转回来  
           BufferedImage image = new BufferedImage(width, height,   
                    BufferedImage.TYPE_INT_RGB);   
            // 获取图形上下文   
            Graphics g = image.getGraphics();   
            // 设定背景色   
            Color background=getColor();  
            g.setColor(background);  
            g.fillRect(0, 0, width, height);   
            //画边框   
            g.setColor(background);  
            g.drawRect(0,0,width-1,height-1);   
            //   将认证码显示到图像中,如果要生成更多位的认证码  
            char[] content=getDrawContent2();  
            int[] xs=getRadonWidths(content.length);  
            int[] ys=getRadomHeights(content.length);  
            for(int i=0;i<content.length;i++)  
            {   String s=content[i]+"";  
                       if(content[i]=='!')  
                           s="";  
                       //如果在画字之前旋转图片  
                if(i!=2){         
                       int maxDegree=rand.nextInt(2);  
                       if(maxDegree==0)  
                        maxDegree=0;  
                       else maxDegree=305;  
               degree=rand.nextInt(45)+maxDegree;             
                }   else degree=0;  
                g.setColor(getColor());   
                if(i==2)//运算符号显示大一些  
                    g.setFont(new Font("Atlantic Inline",Font.PLAIN,24));  
                else  
                g.setFont(new Font("Atlantic Inline",Font.PLAIN,18));            
                RotateString(s, xs[i], ys[i], g, degree);  
            }  
           //画干扰点  
            CreateRandomPoint(width, height, 80, g);         
            //随机画几条线  
            CreateRandomLine(width, height,4,g);          
            // 释放图形上下文  
            g.dispose();  
            System.out.println("计算的结果是="+getResult2());        
            return image;  
        }  
        /** 
         * 旋转并且画出指定字符串 
         * @param s 需要旋转的字符串 
         * @param x 字符串的x坐标 
         * @param y 字符串的Y坐标 
         * @param g 画笔g 
         * @param degree 旋转的角度 
         */  
        private void RotateString(String s,int x,int y,Graphics g,int degree)  
        {  
            Graphics2D g2d = (Graphics2D) g.create();                                    
            //   平移原点到图形环境的中心  ,这个方法的作用实际上就是将字符串移动到某一个位置  
            g2d.translate(x-1, y+3);               
            //   旋转文本    
             g2d.rotate(degree* Math.PI / 180);  
             //特别需要注意的是,这里的画笔已经具有了上次指定的一个位置,所以这里指定的其实是一个相对位置  
             g2d.drawString(s,0 , 0);  
        }  
          
        /** 
         *  
         * @param width 
         * @param height 
         * @param many 
         * @param g 
         */  
        private void CreateRandomPoint(int width,int height,int many,Graphics g)  
        {  // 随机产生干扰点  
            for (int i=0;i<many;i++) {   
                int x = rand.nextInt(width);   
                int y = rand.nextInt(height);   
                g.setColor(getColor());  
                g.drawOval(x,y,1,1);   
            }   
        }  
    /** 
     *  
     * @param width 
     * @param height 
     * @param minMany 最少产生的数量 
     * @param g 
     */  
        private void CreateRandomLine(int width,int height,int minMany,Graphics g)  
        {  // 随机产生干扰线条  
            for (int i=0;i<rand.nextInt(minMany)+5;i++) {   
                int x1 = rand.nextInt(width)%15;   
                int y1 = rand.nextInt(height);  
                int x2 = (int) (rand.nextInt(width)%40+width*0.7);   
                int y2 = rand.nextInt(height);   
                g.setColor(getColor());  
                g.drawLine(x1, y1, x2, y2);  
            }   
        }  
          
        /***  
         * @return 随机返回一种颜色 
         */  
        private Color getColor()  
        {  
            int R=(int) (Math.random()*255);  
            int G=(int) (Math.random()*255);  
            int B=(int) (Math.random()*255);  
        return new Color(R,G,B);  
        }  
        /** 
         *  
         * @return 返回getVerificationCode2需要画出的内容:两位数加减法字符数组 
         */  
        private char[] getDrawContent2()  
        { beijiashu=0;  
          jiashu=0;  
        char[] temp=new char[6];  
        char[] w =aa;    
        int k=0;      
              /** 
               * 产生被加数 
               */  
            //从aa\bb\cc中选择一个字符数组作为素材      
            k=(int)(Math.random()*4);  
            if(k==0)  
              w=aa;  
            else if(k==1) w=bb;  
            else if(k==3) w=cc;  
              k=(int)(Math.random()*10);  
              temp[0]=w[k];  
              if(k==0) temp[0]='!';  
              beijiashu+=k*10;  
              k=(int)(Math.random()*10);  
              temp[1]=w[k];  
              beijiashu+=k;  
              /** 
               * 产生加数 
               */  
            //从aa\bb\cc中选择一个字符数组作为素材      
            k=(int)(Math.random()*4);  
            if(k==0)  
              w=aa;  
            else if(k==1) w=bb;  
            else if(k==3) w=cc;  
               
           k=(int)(Math.random()*10);  
              temp[3]=w[k];  
          if(k==0) temp[3]='!';    
          jiashu=k*10+jiashu;           
            k=(int)(Math.random()*10);  
              temp[4]=w[k];  
              jiashu+=k;  
              //选择加减乘除  
              w=action;  
              k=(int)(Math.random()*4 );  
              temp[2]=w[k];  
              js=k%2;  
              //结果  
              w=jieguo;  
              k=(int)(Math.random()*2);  
              temp[5]=w[k];  
        //System.out.println(new String(temp));  
              return temp;  
        }     
        /** 
         * 对图片选择,这里保留以方便以后使用 
         * @param bufferedimage 
         * @param degree 
         * @return 一张旋转后的图片 
         */  
        public BufferedImage rolateImage(BufferedImage bufferedimage,int degree,Color backGround)  
        {                  
            BufferedImage img;  
            int w = bufferedimage.getWidth();  
            int h = bufferedimage.getHeight();  
            int type = BufferedImage.TYPE_INT_RGB;  
            Graphics2D graphics2d;  
            graphics2d = (img = new BufferedImage(w, h, type)).createGraphics();  
            graphics2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,  
                        RenderingHints.VALUE_INTERPOLATION_BICUBIC);  
            graphics2d.rotate(Math.toRadians(degree), w / 2, h / 2);  
            graphics2d.drawImage(bufferedimage,null, null);   
            return img;  
        }  
          
        /** 
         * 得到验证码getVerificationCode2,计算出来的结果 
         */  
        public int getResult2()  
        { if(js==0)  
            return(beijiashu+jiashu);  
          else if(js==1) return (beijiashu-jiashu);  
            return 0;  
        }  
        /** 
         *  
         * @param many 
         * @return 画图的时候随机的高度的数组 
         */  
        private int[] getRadomHeights(int many){  
            int[] temp=new int[many];   
            for(int i=0;i<many;i++){  
                temp[i]=getRadomHeight();  
            }  
            return temp;  
        }  
        /** 
         *  
         * @param many 
         * @return 画图的时候起始x坐标的数组 
         */  
        private int[] getRadonWidths(int many)  
        { int[] temp=new int[many];   
          for(int i=0;i<many;i++){  
              if(i==0)  
              temp[i]=getRadonWidth(0);  
              else temp[i]=getRadonWidth(temp[i-1]);  
          }  
          return temp;        
        }  
          
        private int getRadomHeight()  
        { int fullHeight=70;  
          return (int)(Math.random()*fullHeight)%35+15;       
        }  
          
        private int getRadonWidth(int minWidth)  
        { int maxWidth=150;  
          int minJianju=maxWidth/9;  
          int maxJianju=maxWidth/6;  
          int temp=maxJianju-minJianju;  
          //在的规定的范围内产生一个随机数  
          return (int)(Math.random()*temp)+minWidth+minJianju;        
        }  
      
      
    }  

运行结果:
20141016100125532.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值