一个生成网页验证码的类 (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;
        // 画出字体
        value = "";
        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) {
                }
            }

        }
    }
}

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

时间: 2024-10-25 15:29:28

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

生成随机验证码工具类

生成随机验证码 package com.web; //验证码生成处理类 import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Line2D; import java.awt.ima

使用Apache POI写的一个生成Excel的工具类

话不多说,直接上代码,就一个类,注释也写得比较清楚了. /** * */ package com.common.office; import java.io.FileOutputStream; import java.lang.reflect.Field; import java.util.Calendar; import java.util.List; import org.apache.commons.collections.CollectionUtils; import org.apach

使用POI做的一个生成Excel的工具类。包含了导出Excel和解析Excel方法

PoiExcelUtils.java /** * */ package com.common.office; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.List;

生成网页验证码

<%@ page language="java" import="java.util.*" import="java.awt.image.*" import="javax.imageio.*" import="java.awt.*" pageEncoding="gbk"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0

Java Web:使用Servlet生成网页随机图片验证码

最近在学习Java Web开发,做了一个生成网页随机图片验证码的例子,在此记录. 一.新建Servlet项目: 在MyEclipse中新建Servlet项目,一步步操作就OK,在此不再赘述.建好之后文件目录树如下图: 二.源代码实现: (1)java代码: package com.zdt.identity; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.

生成验证码的类

<%@ WebHandler Language="C#" Class="ValidateCode" %> using System; using System.Web; using System.Drawing; using System.Web.SessionState; public class ValidateCode : IHttpHandler,IRequiresSessionState { public void ProcessRequest

一个实用的C#网页抓取类代码分享

一个实用的C# 网页抓取类 模拟蜘蛛,类中定义了超多的C#采集文章.网页抓取文章的基础技巧,下面分享代码: using System; using System.Data; using System.Configuration; using System.Net; using System.IO; using System.Text; using System.Collections.Generic; using System.Text.RegularExpressions; using Sys

jsp中生成的验证码和存在session里面的验证码不一致的处理

今天在调试项目的时候发现,在提交表单的时候的验证码有问题,问题是这样的:就是通过debug模式查看得知:jsp页面生成的验证码和表单输入的页面输入的一样,但是到后台执行的时候,你会发现他们是不一样的,现在上图看看: 1.这是表单提交的时候: 2.这是后台得到的生成的验证码: 3.这是后台得到输入的验证码: 这样的问题还是头一次出现,以前没遇到过,经过google,baidu,最后得知是这样的:因为加载jsp页面比加载session快一些 那怎么办才能解决这个办法呢, 又经过多次搜索,思考,实践,

php生成动态验证码

<?php /** *ImageCode 生成包含验证码的GIF图片的函数 *@param $string 字符串 *@param $width 宽度 *@param $height 高度 **/ function ImageCode($string='',$width=75,$height=25){ $authstr=$string?$string:((time()%2==0)?mt_rand(1000,9999):mt_rand(10000,99999)); $board_width=$wi