最近看了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")); }