zoukankan      html  css  js  c++  java
  • 使用Java设计验证码生成程序

        我们来设计一个简单的验证码生成程序:验证码一个由4位的数字、字母随机组合而成图像,为了避免被光学字元识别(OCR,Optical Character Recognition)之类的程序识别出图片中的数字而失去效果,我们给图像中添加上几条干扰线。

      1 package password;
      2 /**
      3  * 使用Java设计验证码生成程序
      4  * @author hellokitty燕
      5  */
      6 import java.awt.Color;
      7 import java.awt.Font;
      8 import java.awt.Graphics;
      9 import java.awt.Graphics2D;
     10 import java.awt.image.BufferedImage;
     11 import java.util.Random;
     12 
     13 import javax.swing.ImageIcon;
     14 import javax.swing.JFrame;
     15 import javax.swing.JLabel;
     16 
     17 public class Verification {
     18     
     19     /*验证码的框*/
     20     // 图像长度
     21     private int width = 100;
     22     // 图像宽度
     23     private int height = 40;
     24     // 验证码的长度
     25     private int number = 4;
     26     // 验证码随机生成的
     27     private String password = "abcdefghijkmnpqrstuvwxyABCDEFGHIJKLMNPQRSTUVWXYZ23456789";
     28 
     29     /**
     30      * 获取验证码图像
     31      * 
     32      * @return 验证码图像
     33      */
     34     public BufferedImage getImage() {
     35         /*BufferedImage 子类描述具有可访问图像数据缓冲区的 Image。
     36          * BufferedImage(int width, int height, int imageType)构造一个类型为预定义图像类型之一的 BufferedImage。
     37          * 
     38          * */
     39         // 创建图像缓冲区
     40         BufferedImage image = new BufferedImage(width, height,
     41                 BufferedImage.TYPE_INT_RGB);
     42         // 获取画笔
     43         /*public Graphics getGraphics()*/
     44         Graphics g = image.getGraphics();
     45         
     46         // 设置图像背景色,填充背景矩形
     47         /*public abstract void setColor(Color c)*/
     48         
     49         
     50         g.setColor(getRandomColor(200, 255));//???        
     51         /*public abstract void fillRect(int x,int y,int width,int height)*/
     52         g.fillRect(0, 0, width, height);
     53 
     54         // 画边框
     55         g.setColor(Color.blue);
     56         g.drawRect(0, 0, width - 1, height - 1);
     57 
     58         /* 生成随机验证码 */
     59         int len = password.length();
     60         // 设置验证码字体 Font(String name, int style, int size)
     61         // HANGING_BASELINE 布置文本时,在 Devanigiri 和类似脚本中使用的基线。
     62         g.setFont(new Font("楷体", Font.HANGING_BASELINE, 20));
     63 
     64         // 循环生成验证码各字符????
     65         Random random = new Random();
     66         for (int i = 0; i < number; i++) {
     67             // 随机生成验证码中单个字符/*public int nextInt(int n)返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int 值*/
     68             String randStr = String.valueOf(password.charAt(random.nextInt(len)));
     69             // 单个字符绘制宽度
     70             int width = this.width / this.number;
     71             // 当前字符绘制原点   ????
     72             int x = width * i;
     73             int y = this.height / 2 + random.nextInt(this.height / 3);
     74             /* 将该字符画到图像中 */// ???
     75             drawString(g, x, y, randStr);
     76 
     77         }
     78 
     79         // 画干扰线
     80         drawLine(g, 10);
     81 
     82         // 释放画笔
     83         g.dispose();
     84         return image;
     85 
     86     }
     87 
     88     /**
     89      * 画验证码字符串单个字符
     90      * 
     91      * @param g
     92      *            图像上下文
     93      * @param x
     94      *            字符 所占宽度
     95      * @param y
     96      *            字符所占高度
     97      * @param randStr
     98      *            待绘制字符串
     99      * 
    100      */
    101  private void drawString(Graphics g,int width,int height,String randStr){
    102     //private void drawString(Graphics g, int x, int y, String randStr) {
    103         Random rand = new Random();
    104         // 随机生成字符旋转(-30-30度)/*/*public int nextInt(int n)返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int 值*/*/
    105         int degree = rand.nextInt(60);
    106         if (degree > 30) {
    107             degree = 30 - degree;
    108         }
    109         // 设置字体颜色
    110         g.setColor(getRandomColor(0, 50));
    111         // 转换Graphics2D
    112         Graphics2D g2 = (Graphics2D) g.create();
    113         // 平移原点到图形环境的中心,这个方法的作用实际上就是将字符串移到某一位置/*public abstract void translate(int x,int y)将 Graphics2D 上下文的原点平移到当前坐标系中的点 (x, y)。*/
    114         g2.translate(width + rand.nextInt(5), height + rand.nextInt(5));
    115         // 旋转文本   ( 单位是弧度)
    116         g2.rotate(degree * Math.PI / 180);
    117         // 画文本,特别需要注意的是,这里的笔画已经具有上次指定的一个位置,所以这里指定的位置是一个相对的位置
    118         g2.drawString(randStr, 0, 0);
    119     }
    120 
    121     /**
    122      * 
    123      * 画 随机干扰线
    124      * 
    125      * @param g
    126      *            图形上下文(画笔)
    127      * 
    128      * @param count
    129      *            干扰线条数
    130      */
    131     private void drawLine(Graphics g,int count){
    132     
    133         Random random = new Random();
    134         // 循环绘制每条干扰线
    135         for (int j = 0; j < count; j++) {
    136             // 设置线条随机颜色
    137             g.setColor(getRandomColor(180, 200));
    138             
    139             // 生成随机线条起点终点,坐标点
    140             int x1 = random.nextInt(this.width);
    141             int y1 = random.nextInt(this.height);
    142             int x2 = random.nextInt(this.width);
    143             int y2 = random.nextInt(this.height);
    144             // 画线条
    145             g.drawLine(x1, y1, x2, y2);
    146         }
    147     }
    148 
    149     /**
    150      * 获取随机颜色
    151      * 
    152      * @param i
    153      *            颜色下限值
    154      * @param j
    155      *            颜色上限值
    156      * @return 随机颜色对象
    157      */
    158     private Color getRandomColor(int i, int j) {
    159         if (i > j) {
    160             int tmp = i;
    161             i = j;
    162             j = tmp;
    163         }
    164         if (j > 225) {
    165             j = 225;
    166         }
    167         if (i < 0) {
    168             i = 0;
    169         }
    170         int r = i + (int) (Math.random() * (j - i));
    171         int g = i + (int) (Math.random() * (j - i));
    172         int b = i + (int) (Math.random() * (j - i));
    173 
    174         return new Color(r, g, b);
    175         
    176 //        values in the range (0 - 255). red green blue
    177     }
    178 
    179     public static void main(String[] args) {
    180 
    181         JFrame frame = new JFrame("验证码");
    182         frame.setSize(200, 200);
    183         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    184         frame.setLocationRelativeTo(null);
    185         Verification cation = new Verification();
    186         
    187         JLabel lbl = new JLabel(new ImageIcon(cation.getImage()));
    188         frame.add(lbl);
    189         frame.setVisible(true);
    190 
    191     }
    192 
    193 }

                  

  • 相关阅读:
    清理git提交记录并不能达到真正硬盘“瘦身”
    virtualbox虚拟机异常暂停
    百兆带宽升千兆-番外篇
    流水文之百兆带宽升千兆
    OSS设置静态网站托管+CDN加速OSS域名
    每日一坑-exsi中win虚拟机调分辨率
    nginx筛选字段+excel统计
    树莓派使用Samba共享文件
    chrome无法使用独显解决
    解决jdk16安装后无jre目录的问题
  • 原文地址:https://www.cnblogs.com/hellokitty1/p/4508677.html
Copyright © 2011-2022 走看看