使用Java设计验证码生成程序


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

package password;
/**
 * 使用Java设计验证码生成程序
 * @author hellokitty燕
 */
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Verification {
   
    /*验证码的框*/
    // 图像长度
    private int width = 100;
    // 图像宽度
    private int height = 40;
    // 验证码的长度
    private int number = 4;
    // 验证码随机生成的
    private String password = "abcdefghijkmnpqrstuvwxyABCDEFGHIJKLMNPQRSTUVWXYZ23456789";

    /**
    * 获取验证码图像
    *
    * @return 验证码图像
    */
    public BufferedImage getImage() {
        /*BufferedImage 子类描述具有可访问图像数据缓冲区的 Image。
        * BufferedImage(int width, int height, int imageType)构造一个类型为预定义图像类型之一的 BufferedImage。
        *
        * */
        // 创建图像缓冲区
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        // 获取画笔
        /*public Graphics getGraphics()*/
        Graphics g = image.getGraphics();
       
        // 设置图像背景色,填充背景矩形
        /*public abstract void setColor(Color c)*/
       
       
        g.setColor(getRandomColor(200, 255));//???       
        /*public abstract void fillRect(int x,int y,int width,int height)*/
        g.fillRect(0, 0, width, height);

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

        /* 生成随机验证码 */
        int len = password.length();
        // 设置验证码字体 Font(String name, int style, int size)
        // HANGING_BASELINE 布置文本时,在 Devanigiri 和类似脚本中使用的基线。
        g.setFont(new Font("楷体", Font.HANGING_BASELINE, 20));

        // 循环生成验证码各字符????
        Random random = new Random();
        for (int i = 0; i < number; i++) {
            // 随机生成验证码中单个字符/*public int nextInt(int n)返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int 值*/
            String randStr = String.valueOf(password.charAt(random.nextInt(len)));
            // 单个字符绘制宽度
            int width = this.width / this.number;
            // 当前字符绘制原点  ????
            int x = width * i;
            int y = this.height / 2 + random.nextInt(this.height / 3);
            /* 将该字符画到图像中 */// ???
            drawString(g, x, y, randStr);

        }

        // 画干扰线
        drawLine(g, 10);

        // 释放画笔
        g.dispose();
        return image;

    }

    /**
    * 画验证码字符串单个字符
    *
    * @param g
    *            图像上下文
    * @param x
    *            字符 所占宽度
    * @param y
    *            字符所占高度
    * @param randStr
    *            待绘制字符串
    *
    */
 private void drawString(Graphics g,int width,int height,String randStr){
    //private void drawString(Graphics g, int x, int y, String randStr) {
        Random rand = new Random();
        // 随机生成字符旋转(-30-30度)/*/*public int nextInt(int n)返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int 值*/*/
        int degree = rand.nextInt(60);
        if (degree > 30) {
            degree = 30 - degree;
        }
        // 设置字体颜色
        g.setColor(getRandomColor(0, 50));
        // 转换Graphics2D
        Graphics2D g2 = (Graphics2D) g.create();
        // 平移原点到图形环境的中心,这个方法的作用实际上就是将字符串移到某一位置/*public abstract void translate(int x,int y)将 Graphics2D 上下文的原点平移到当前坐标系中的点 (x, y)。*/
        g2.translate(width + rand.nextInt(5), height + rand.nextInt(5));
        // 旋转文本  ( 单位是弧度)
        g2.rotate(degree * Math.PI / 180);
        // 画文本,特别需要注意的是,这里的笔画已经具有上次指定的一个位置,所以这里指定的位置是一个相对的位置
        g2.drawString(randStr, 0, 0);
    }

    /**
    *
    * 画 随机干扰线
    *
    * @param g
    *            图形上下文(画笔)
    *
    * @param count
    *            干扰线条数
    */
    private void drawLine(Graphics g,int count){
   
        Random random = new Random();
        // 循环绘制每条干扰线
        for (int j = 0; j < count; j++) {
            // 设置线条随机颜色
            g.setColor(getRandomColor(180, 200));
           
            // 生成随机线条起点终点,坐标点
            int x1 = random.nextInt(this.width);
            int y1 = random.nextInt(this.height);
            int x2 = random.nextInt(this.width);
            int y2 = random.nextInt(this.height);
            // 画线条
            g.drawLine(x1, y1, x2, y2);
        }
    }

    /**
    * 获取随机颜色
    *
    * @param i
    *            颜色下限值
    * @param j
    *            颜色上限值
    * @return 随机颜色对象
    */
    private Color getRandomColor(int i, int j) {
        if (i > j) {
            int tmp = i;
            i = j;
            j = tmp;
        }
        if (j > 225) {
            j = 225;
        }
        if (i < 0) {
            i = 0;
        }
        int r = i + (int) (Math.random() * (j - i));
        int g = i + (int) (Math.random() * (j - i));
        int b = i + (int) (Math.random() * (j - i));

        return new Color(r, g, b);
       
//        values in the range (0 - 255). red green blue
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame("验证码");
        frame.setSize(200, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        Verification cation = new Verification();
       
        JLabel lbl = new JLabel(new ImageIcon(cation.getImage()));
        frame.add(lbl);
        frame.setVisible(true);

    }

}

             

本文永久更新链接地址

相关内容

    暂无相关文章