首页 > 代码库 > 一个生成网页验证码的类 (mycome-validate)

一个生成网页验证码的类 (mycome-validate)

一个小练习

可以通过 BufferedImage next() 返回一个内存图片

也可以通过String void next(OutputStream out) 写到一个输出流中,并返回验证码的值

jar包下载:http://files.cnblogs.com/mycome/mycome-validate.zip

package validate;import java.awt.Color;import java.awt.Font;import java.awt.Graphics2D;import java.awt.image.BufferedImage;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.OutputStream;import javax.imageio.ImageIO;public class Validate {    // 支持的验证码干扰效果    public static final int ROTATE = Integer.parseInt("00000001", 2);// 旋转    public static final int CIRCLE = Integer.parseInt("00000010", 2);// 干扰圈    public static final int LINE = Integer.parseInt("00000100", 2);// 干扰线    public static final int FOG = Integer.parseInt("00001000", 2);// 雾化    public static final int LIGHTER = Integer.parseInt("00010000", 2);// 颜色变淡    // 验证码属性    private int width; // 尺寸    private int height;    private int size;// 字符数    private int fontSize;// 字体大小    private int interval;// 字符间隔    private int obstruction;// 干扰效果    private String value;// 验证码的字符值    private Graphics2D graphics;// 绘图器    private BufferedImage validate;// 结果对象    private String range;// 取字范围    // 构造方法    public Validate(int width, int height, int size, int obstruction,            String rangeSource) {        // 初始化验证码的尺寸        this.width = width;        this.height = height;        // 初始化验证码的字符数        this.size = size;        // 设定验证码的干扰效果        this.obstruction = obstruction;        // 设定字体大小和间隔        calculateSize();        // 设置验证码范围        setRange(rangeSource);    }    // 生成验证码    public BufferedImage next() {        // 生成图片        validate = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);        graphics = (Graphics2D) validate.getGraphics();        addBackground();        // 添加文字        addCharacters();        // 添加干扰        addObstruction();        return validate;    }    // 把验证码图片当作流输出    public String next(OutputStream out) throws IOException {        next();        ImageIO.write(validate, "jpg", out);        return value;    }    // 设置背景色    private void addBackground() {        // 设置背景色为淡灰色        graphics.setColor(new Color(0xf8f8f8));        graphics.fillRect(0, 0, width, height);    }    // 添加文字    private void addCharacters() {        // 设置字体        graphics.setFont(new Font("宋体", Font.BOLD, fontSize));        graphics.setColor(Color.black);        // 字符位置标记        int x = 0;        int y = (height - fontSize) / 2 + fontSize;        Character c;        // 取字范围        int len = range.length();        // 判断是否需要旋转        boolean doRotate = (obstruction % 2) != 0 ? true : false;        double radian = 0;        // 画出字体        valuehttp://www.mamicode.com/= "";        for (int i = 0; i < size; i++) {            x += interval;            // 设定旋转角度            if (doRotate)                radian = Math.random() * Math.PI / 3 - Math.PI / 6;            if (doRotate)                graphics.rotate(radian, x + fontSize / 2, y - fontSize / 2);            // 取字,画字            c = range.charAt((int) (Math.random() * len));            value += c.toString();            graphics.drawString(c.toString(), x, y);            // 恢复旋转角度            if (doRotate)                graphics.rotate(-radian, x + fontSize / 2, y - fontSize / 2);            x += fontSize;        }    }    // 画干扰物    private void addObstruction() {        // 定义变量        boolean needCircle = false;        boolean needLine = false;        boolean needFog = false;        boolean needLighter = false;        // 为以上变量赋值        if ((obstruction & CIRCLE) == CIRCLE)            needCircle = true;        if ((obstruction & LINE) == LINE)            needLine = true;        if ((obstruction & FOG) == FOG)            needFog = true;        if ((obstruction & LIGHTER) == LIGHTER)            needLighter = true;        // 添加干扰物        if (needCircle)            addCircle();        if (needLine)            addLine();        if (needFog)            addFog();        if (needLighter)            addLighter();    }    // 增加验证码图片的亮度    private void addLighter() {        for (int i = 0; i < width; i++) {            for (int j = 0; j < height; j++) {                // 获得原来的颜色                int color = validate.getRGB(i, j);                color += 256 * 256 * 4;                color += 256 * 4;                color += 4;                // 设置更亮的颜色                validate.setRGB(i, j, color);            }        }    }    // 添加雾化效果    private void addFog() {        // 设置雾化的颜色是灰色        Color pointColor = Color.DARK_GRAY;        // 设置雾化的密度是1/4;        for (int i = 0; i < width; i += 4) {            for (int j = 0; j < height; j += 4) {                validate.setRGB(i, j, pointColor.getRGB());            }        }    }    // 添加干扰线    private void addLine() {        // 定义干扰线的起点和终点        int startX;        int startY;        int endX;        int endY;        // 设置颜色        graphics.setColor(Color.GRAY);        // 画干扰线        for (int i = 0; i < 5; i++) {            startX = (int) (Math.random() * width);            startY = (int) (Math.random() * height);            endX = (int) (Math.random() * width);            endY = (int) (Math.random() * height);            graphics.drawLine(startX, startY, endX, endY);        }    }    // 添加干扰圈    private void addCircle() {        int x;        int y;        int oval;        for (int i = 0; i < 5; i++) {            x = (int) (Math.random() * width);            y = (int) (Math.random() * height);            oval = (int) (Math.random() * (height / 2 - 5));            graphics.drawOval(x, y, oval, oval);        }    }    // 设定字体大小和间隔    private void calculateSize() {        int interval;        int fontSize;        // 计算合适的字体尺寸        int accordingToWidth = (width - ((size + 1) * 5)) / size;        int accordingToHeight = height - 10;        fontSize = accordingToWidth < accordingToHeight ? accordingToWidth                : accordingToHeight;        // 计算合适的间隔尺寸        interval = (width - (fontSize * size)) / (size + 1);        // 初始化成员变量        this.fontSize = fontSize;        this.interval = interval;    }    // 设置验证码的取字范围    private void setRange(String rangeSource) {        FileInputStream in = null;        byte[] buf = new byte[1024];        int len;        // 从文件读取数据        try {            in = new FileInputStream(rangeSource);            while ((len = in.read(buf, 0, 1024)) > 0) {                range += new String(buf, 0, len);            }        } catch (FileNotFoundException e) {            new RuntimeException("读取验证码取字范围失败", e);        } catch (IOException e) {            new RuntimeException("读取验证码取字范围失败", e);        } finally {            if (in != null) {                try {                    in.close();                } catch (IOException e) {                }            }        }    }}