java. gif动画验证码的实现

废话少说,直奔主题。

目标:实现GIF动画格式的验证码。

效果图:

说明:此GIF格式验证码有6个字符组成,共有6帧,单独每帧只有5个字符,每帧的每个字符的透明度不等,显示闪烁效果。也可以做成垂直位置变化的动画效果。 或者类似QQ的那样字体倾斜。

用到第三方类文件:一个老外写的。专门用来解GIF码的,

一共4个,类名:AnimatedGifEncoder,GifDecoder,LZWEncoder,NeuQuant;这几个类网上搜下应该有的。

就不贴了哈,有找不到的加我QQ 87388066,或者留信箱。BLOG没上传附件功能,比较郁闷。

下面贴下我的简单实现:

import jalion.giftools.AnimatedGifEncoder;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

import javax.servlet.http.HttpServletResponse;

public class Test2 {
//定义验证码字符。去除了O和I等容易混淆的字母(也可写成)
String s[]={"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"};
//定义生成的验证码的宽度和高度
int width=160;
int height=30;

public void myTest(OutputStream os)
{
//OutputStream os=null;

//生成字符
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,1);
AnimatedGifEncoder agf=new AnimatedGifEncoder();

agf.start(os);
agf.setQuality(10);

agf.setDelay(100);
agf.setRepeat(0);
BufferedImage frame=null;
Graphics2D teg=null;
String rands[]=new String[6];
for(int i=0;i<6;i++)
{
rands[i]=s[this.randomInt(0, s.length)];
}
//生成字体
Font font[]=new Font[6];
for(int i=0;i<6;i++)
{
font[i]=this.getFont();
}
//生成背景颜色
Color bgcolor=getRandColor(160, 200);
Color linecolor=getRandColor(200, 250);
Color fontcolor[]=new Color[6];
Random random=new Random();
for(int i=0;i<6;i++)
{
fontcolor[i]=new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110));
}
for(int i=0;i<6;i++)
{
frame=this.getImage(bgcolor,linecolor,fontcolor,rands,font,i);
agf.addFrame(frame);
frame.flush();
}
agf.finish();
}
private BufferedImage getImage(Color bgcolor,Color linecolor,Color[] fontcolor,String str[],Font[] font,int flag)
{
BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
//或得图形上下文
Graphics2D g2d=image.createGraphics();
//利用指定颜色填充背景
g2d.setColor(bgcolor);
g2d.fillRect(0, 0, width, height);
//画背景线 4*4
g2d.setColor(linecolor);
for (int i = 0; i < height/4; i++) {

g2d.drawLine(0, i*4, width, i*4);
}
for (int i = 0; i <width/4; i++) {

g2d.drawLine(i*4, 0, i*4, height);
}
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f);
g2d.setComposite(ac);
g2d.setFont(new Font("隶书", Font.ITALIC+Font.BOLD, 26));
g2d.setColor(Color.red);
g2d.drawString("jalion制作", 19, 25);


//以下生成验证码 //透明度从0 循环到1 步长为0.2 。一共6个字母
AlphaComposite ac3 =null;
for(int i=0;i<str.length;i++)
{
g2d.setFont(font[i]);
ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getAlpha(flag, i));
g2d.setComposite(ac3);
g2d.setColor(fontcolor[i]);

g2d.drawString(str[i], 25 * i + 8, 25);
}
g2d.dispose();
return image;
}

/**
*
* @作者:李桢
* @日期:2007-6-27
* @参数:
* @返回值:
* @描述:获得随机字体
*/
private Font getFont()
{
//获得随机字体;
//设置font :字体名称:Monotype Corsiva 华文彩云 方正舒体 华文行楷,隶书

Random s=new Random();
//int i=s.nextInt(10);
int i=7;
if(i%2==0)
{
return new Font("Monotype Corsiva", Font.BOLD, 28);
}
else if(i%3==0)
{
return new Font("方正舒体", Font.BOLD, 28);
}
//else if(i%5==0)
//{
//return new Font("华文行楷", Font.BOLD, 28);
//}
else if(i%7==0)
{
return new Font("隶书", Font.BOLD, 28);
}
else
{
return new Font("方正舒体", Font.BOLD, 28);
}
}


/**
*
* @作者:李桢
* @日期:2007-6-27
* @参数:
* @返回值:
* @描述:获得循环透明度,从0到1 步长为0.2
*/
private float getAlpha(int i,int j)
{
if((i+j)>5)
{

return ((i+j)*0.2f-1.2f);
}
else
{
return (i+j)*0.2f;
}
}
/**
*
* @作者:李桢
* @日期:2007-6-27
* @参数:
* @返回值:
* @描述:获得随机色
*/
private Color getRandColor(int fc, int bc) {// 给定范围获得随机颜色
Random random = new Random();
if (fc > 255)
fc = 255;
if (bc > 255)
bc = 255;
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}
/**
* 返回[from,to)之间的一个随机整数
*
* @param from 起始值
* @param to 结束值
* @return [from,to)之间的一个随机整数
*/
private int randomInt(int from,int to){
Random r = new Random();
return from+r.nextInt(to-from);
}
public static void main(String args[])
{
Test2 tt=new Test2();
//tt.myTest();
}
}

servlet:

public class yanzhengma extends HttpServlet {
// Initialize global variables
public void init() throws ServletException {
}

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("image/gif");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);

new Test2().myTest(response.getOutputStream());

}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}

// 这是POST,和GET差不多,不过HTTP有POST和GET两种请求方式罢了
// Clean up resources
public void destroy() {

}


}

web.xml

<!-- 验证码servlet 开始 -->
<servlet>
<servlet-name>yanzhengma</servlet-name>
<servlet-class>jalion.image.yanzhengma</servlet-class>
</servlet>


<servlet-mapping>
<servlet-name>yanzhengma</servlet-name>
<url-pattern>/servlet/yanzhengma</url-pattern>
</servlet-mapping>

<!-- 验证码servlet 结束 -->

页面中调用

<img src="servlet/yanzhengma"/>

好了到此为止了,困了。。。,

再生成验证码字符串的地方把验证码加到cookie或者session里。

好像outputstream没有关闭。。标记下,改天再说 需要改动老外那个类。困了 睡觉了。

FROM:http://jalion.blog.sohu.com/52684861.html

你可能感兴趣的:(java)