现在的位置: 首页 > 综合 > 正文

java 生成验证码(包含gif动画验证码)

2017年08月13日 ⁄ 综合 ⁄ 共 6174字 ⁄ 字号 评论关闭

最近看了PHP写的动画gif验证码,于是用Java实现了类似的,代码不是很良好,将就着看。。

代码包含Gif编码解码四个类,在附件中,自行下载。

import java.awt.*;
import java.io.OutputStream;
 
import static Randoms.num;
import static Randoms.alpha;
/**
 * <p>验证码抽象类,暂时不支持中文</p>
 *
 * @author: wuhongjun
 * @version:1.0
 */
public abstract class Captcha
{
    protected Font font = new Font("Verdana", Font.ITALIC|Font.BOLD, 28);   // 字体
    protected int len = 5;  // 验证码随机字符长度
    protected int width = 150;  // 验证码显示跨度
    protected int height = 40;  // 验证码显示高度
    private String chars = null;  // 随机字符串
 
    /**
     * 生成随机字符数组
     * @return 字符数组
     */
    protected char[] alphas()
    {
        char[] cs = new char[len];
        for(int i = 0;i<len;i++)
        {
            cs[i] = alpha();
        }
        chars = new String(cs);
        return cs;
    }
    public Font getFont()
    {
        return font;
    }
 
    public void setFont(Font font)
    {
        this.font = font;
    }
 
    public int getLen()
    {
        return len;
    }
 
    public void setLen(int len)
    {
        this.len = len;
    }
 
    public int getWidth()
    {
        return width;
    }
 
    public void setWidth(int width)
    {
        this.width = width;
    }
 
    public int getHeight()
    {
        return height;
    }
 
    public void setHeight(int height)
    {
        this.height = height;
    }
 
    /**
     * 给定范围获得随机颜色
     * @return Color 随机颜色
     */
    protected Color color(int fc, int bc)
    {
        if (fc > 255)
            fc = 255;
        if (bc > 255)
            bc = 255;
        int r = fc + num(bc - fc);
        int g = fc + num(bc - fc);
        int b = fc + num(bc - fc);
        return new Color(r, g, b);
    }
 
    /**
     * 验证码输出,抽象方法,由子类实现
     * @param os 输出流
     */
    public abstract void out(OutputStream os);
 
    /**
     * 获取随机字符串
     * @return string
     */
    public String text()
    {
        return chars;
    }
}

png格式验证码

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import static Randoms.num;
/**
 * <p>png格式验证码</p>
 *
 * @author: wuhongjun
 * @version:1.0
 */
public class SpecCaptcha extends Captcha
{
    public SpecCaptcha()
    {
    }
    public SpecCaptcha(int width, int height)
    {
        this.width = width;
        this.height = height;
    }
    public SpecCaptcha(int width, int height, int len){
        this(width,height);
        this.len = len;
    }
    public SpecCaptcha(int width, int height, int len, Font font){
        this(width,height,len);
        this.font = font;
    }
    /**
     * 生成验证码
     * @throws java.io.IOException IO异常
     */
    @Override
    public void out(OutputStream out){
        graphicsImage(alphas(), out);
    }
 
    /**
     * 画随机码图
     * @param strs 文本
     * @param out 输出流
     */
    private boolean graphicsImage(char[] strs, OutputStream out){
        boolean ok = false;
        try
        {
            BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
            Graphics2D g = (Graphics2D)bi.getGraphics();
            AlphaComposite ac3;
            Color color ;
            int len = strs.length;
            g.setColor(Color.WHITE);
            g.fillRect(0,0,width,height);
            // 随机画干扰的蛋蛋
            for(int i=0;i<15;i++){
                color = color(150, 250);
                g.setColor(color);
                g.drawOval(num(width), num(height), 5+num(10), 5+num(10));// 画蛋蛋,有蛋的生活才精彩
                color = null;
            }
            g.setFont(font);
            int h  = height - ((height - font.getSize()) >>1),
                w = width/len,
                size = w-font.getSize()+1;
            /* 画字符串 */
            for(int i=0;i<len;i++)
            {
                ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f);// 指定透明度
                g.setComposite(ac3);
                color = new Color(20 + num(110), 20 + num(110), 20 + num(110));// 对每个字符都用随机颜色
                g.setColor(color);
                g.drawString(strs[i]+"",(width-(len-i)*w)+size, h-4);
                color = null;
                ac3 = null;
            }
            ImageIO.write(bi, "png", out);
            out.flush();
            ok = true;
        }catch (IOException e){
            ok = false;
        }finally
        {
            Streams.close(out);
        }
        return ok;
    }
}

Gif验证码类  

import Streams;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.OutputStream;
import static Randoms.num;
/**
 * <p>Gif验证码类</p>
 *
 * @author: wuhongjun
 * @version:1.0
 */
public class GifCaptcha extends Captcha
{
    public GifCaptcha()
    {
    }
 
    public GifCaptcha(int width,int height){
        this.width = width;
        this.height = height;
    }
 
    public GifCaptcha(int width,int height,int len){
        this(width,height);
        this.len = len;
    }
 
    public GifCaptcha(int width,int height,int len,Font font)
    {
        this(width,height,len);
        this.font = font;
    }
 
    @Override
    public void out(OutputStream os)
    {
        try
        {
            GifEncoder gifEncoder = new GifEncoder();   // gif编码类,这个利用了洋人写的编码类,所有类都在附件中
            //生成字符
            gifEncoder.start(os);
            gifEncoder.setQuality(180);
            gifEncoder.setDelay(100);
            gifEncoder.setRepeat(0);
            BufferedImage frame;
            char[] rands =alphas();
            Color fontcolor[]=new Color[len];
            for(int i=0;i<len;i++)
            {
                fontcolor[i]=new Color(20 + num(110), 20 + num(110), 20 + num(110));
            }
            for(int i=0;i<len;i++)
            {
                frame=graphicsImage(fontcolor, rands, i);
                gifEncoder.addFrame(frame);
                frame.flush();
            }
            gifEncoder.finish();
        }finally
        {
            Streams.close(os);
        }
 
    }
 
    /**
     * 画随机码图
     * @param fontcolor 随机字体颜色
     * @param strs 字符数组
     * @param flag 透明度使用
     * @return BufferedImage
     */
    private BufferedImage graphicsImage(Color[] fontcolor,char[] strs,int flag)
    {
        BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
        //或得图形上下文
        //Graphics2D g2d=image.createGraphics();
        Graphics2D g2d = (Graphics2D)image.getGraphics();
        //利用指定颜色填充背景
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, width, height);
        AlphaComposite ac3;
        int h  = height - ((height - font.getSize()) >>1) ;
        int w = width/len;
        g2d.setFont(font);
        for(int i=0;i<len;i++)
        {
            ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getAlpha(flag, i));
            g2d.setComposite(ac3);
            g2d.setColor(fontcolor[i]);
            g2d.drawOval(num(width), num(height), 5+num(10), 5+num(10));
            g2d.drawString(strs[i]+"", (width-(len-i)*w)+(w-font.getSize())+1, h-4);
        }
        g2d.dispose();
        return image;
    }
 
    /**
     * 获取透明度,从0到1,自动计算步长
     * @return float 透明度
     */
    private float getAlpha(int i,int j)
    {
        int num = i+j;
        float r = (float)1/len,s = (len+1) * r;
        return num > len ? (num *r - s) : num * r;
    }
 
}

Streams IO工具类 

public class Streams
{
    /**
     * 关闭输入流
     * @param in 输入流
     */
    public static void close(InputStream in) {
        if (in != null) {
            try {
                in.close();
            } catch (IOException ioex) {
                // ignore
            }
        }
    }
 
    /**
     * 关闭输出流
     * @param out 输出流
     */
    public static void close(OutputStream out) {
        if (out != null) {
            try {
                out.flush();
            } catch (IOException ioex) {
                // ignore
            }
            try {
                out.close();
            } catch (IOException ioex) {
                // ignore
            }
        }
    }
}

Randoms 随机数工具类 

/**
 * <p>随机工具类</p>
 *
 * @author: wuhongjun
 * @version:1.0
 */
public class Randoms
{
    private static final Random RANDOM = new Random();
    //定义验证码字符.去除了O和I等容易混淆的字母
    public static final char ALPHA[]={'A','B','C','D','E','F','G','H','G','K','M','N','P','Q','R','S','T','U','V','W','X','Y','Z'
            ,'a','b','c','d','e','f','g','h','i','j','k','m','n','p','q','r','s','t','u','v','w','x','y','z','2','3','4','5','6','7','8','9'};
 
    /**
     * 产生两个数之间的随机数
     * @param min 小数
     * @param max 比min大的数
     * @return int 随机数字
     */
    public static int num(int min, int max)
    {
        return min + RANDOM.nextInt(max - min);
    }
 
    /**
     * 产生0--num的随机数,不包括num
     * @param num 数字
     * @return int 随机数字
     */
    public static int num(int num)
    {
        return RANDOM.nextInt(num);
    }
 
    public static char alpha()
    {
        return ALPHA[num(0, ALPHA.length)];
    }
}

Gif编码解码类,总共四个.zip ~ 16KB

http://download.csdn.net/detail/qilixiang012/8311995


PNG格式验证码.png

GIF动画验证码.gif


使用说明,web请用response的输出流

public static void main(String[] args) throws FileNotFoundException
    {
        Captcha captcha = new SpecCaptcha(150,40,5);// png格式验证码
        captcha.out(new FileOutputStream("E:/1.png"));
        captcha = new GifCaptcha(150,40,5);//   gif格式动画验证码
        captcha.out(new FileOutputStream("E:/1.gif"));
    }

转载自:http://www.oschina.net/code/snippet_99424_23429

抱歉!评论已关闭.