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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值