Home > Article > Backend Development > php生成gif动态验证码图片
发一个真正能运行的通过php生成的动态验证码图片的示例。网上下载的好多都报错的,于是自己综合各方面的见解,终于完成了这么一个效果。
下面是php生成动态验证码需要用到的相关类和函数。
<p><?php</p>/**<br />*ImageCode 生成包含验证码的GIF图片的函数<br />*@param $string 字符串<br />*@param $width 宽度<br />*@param $height 高度<br />**/<br />function ImageCode($string='',$width=75,$height=25){<br /> $authstr=$string?$string:((time()%2==0)?mt_rand(1000,9999):mt_rand(10000,99999));<br /> $board_width=$width;<br /> $board_height=$height;<br /> // 生成一个32帧的GIF动画<br /> for($i=0;$i<32;$i++){<br /> ob_start();<br /> $image=imagecreate($board_width,$board_height);<br /> imagecolorallocate($image,0,0,0);<br /> // 设定文字颜色数组 <br /> $colorList[]=ImageColorAllocate($image,15,73,210);<br /> $colorList[]=ImageColorAllocate($image,0,64,0);<br /> $colorList[]=ImageColorAllocate($image,0,0,64);<br /> $colorList[]=ImageColorAllocate($image,0,128,128);<br /> $colorList[]=ImageColorAllocate($image,27,52,47);<br /> $colorList[]=ImageColorAllocate($image,51,0,102);<br /> $colorList[]=ImageColorAllocate($image,0,0,145);<br /> $colorList[]=ImageColorAllocate($image,0,0,113);<br /> $colorList[]=ImageColorAllocate($image,0,51,51);<br /> $colorList[]=ImageColorAllocate($image,158,180,35);<br /> $colorList[]=ImageColorAllocate($image,59,59,59);<br /> $colorList[]=ImageColorAllocate($image,0,0,0);<br /> $colorList[]=ImageColorAllocate($image,1,128,180);<br /> $colorList[]=ImageColorAllocate($image,0,153,51);<br /> $colorList[]=ImageColorAllocate($image,60,131,1);<br /> $colorList[]=ImageColorAllocate($image,0,0,0);<br /> $fontcolor=ImageColorAllocate($image,0,0,0);<br /> $gray=ImageColorAllocate($image,245,245,245);<br /> $color=imagecolorallocate($image,255,255,255);<br /> $color2=imagecolorallocate($image,255,0,0);<br /> imagefill($image,0,0,$gray);<br /> $space=15;// 字符间距<br /> if($i>0){// 屏蔽第一帧<br /> $top=0;<br /> for($k=0;$k<strlen($authstr);$k++){ <br /> $colorRandom=mt_rand(0,sizeof($colorList)-1);<br /> $float_top=rand(0,4);<br /> $float_left=rand(0,3);<br /> imagestring($image,6,$space*$k,$top+$float_top,substr($authstr,$k,1),$colorList[$colorRandom]);<br /> }<br /> }<br /> for($k=0;$k<20;$k++){ <br /> $colorRandom=mt_rand(0,sizeof($colorList)-1);<br /> imagesetpixel($image,rand()%70,rand()%15,$colorList[$colorRandom]);<br /> <br /> }<br /> // 添加干扰线<br /> for($k=0;$k<3;$k++){<br /> $colorRandom=mt_rand(0,sizeof($colorList)-1);<br /> $todrawline=1;<br /> if($todrawline){<br /> imageline($image,mt_rand(0,$board_width),mt_rand(0,$board_height),mt_rand(0,$board_width),mt_rand(0,$board_height),$colorList[$colorRandom]);<br /> }else{<br /> $w=mt_rand(0,$board_width);<br /> $h=mt_rand(0,$board_width);<br /> imagearc($image,$board_width-floor($w / 2),floor($h / 2),$w,$h, rand(90,180),rand(180,270),$colorList[$colorRandom]);<br /> }<br /> }<br /> imagegif($image);<br /> imagedestroy($image);<br /> $imagedata[]=ob_get_contents();<br /> ob_clean();<br /> ++$i;<br /> }<br /> $gif=new GIFEncoder($imagedata);<br /> Header('Content-type:image/gif');<br /> echo $gif->GetAnimation();<br />}<br /><br /><br />/**<br />*GIFEncoder类<br />**/<br />Class GIFEncoder{<br /> var $GIF="GIF89a"; /* GIF header 6 bytes */ <br /> var $VER="GIFEncoder V2.06"; /* Encoder version */ <br /> var $BUF=Array();<br /> var $LOP=0;<br /> var $DIS=2;<br /> var $COL=-1;<br /> var $IMG=-1;<br /> var $ERR=Array(<br /> 'ERR00'=>"Does not supported function for only one image!", <br /> 'ERR01'=>"Source is not a GIF image!", <br /> 'ERR02'=>"Unintelligible flag ", <br /> 'ERR03'=>"Could not make animation from animated GIF source", <br /> );<br /> function GIFEncoder($GIF_src,$GIF_dly=100,$GIF_lop=0,$GIF_dis=0, $GIF_red=0,$GIF_grn=0,$GIF_blu=0,$GIF_mod='bin'){<br /> if(!is_array($GIF_src)&&!is_array($GIF_tim)){<br /> printf("%s: %s",$this->VER,$this->ERR['ERR00']);<br /> exit(0);<br /> } <br /> $this->LOP=($GIF_lop>-1)?$GIF_lop:0;<br /> $this->DIS=($GIF_dis>-1)?(($GIF_dis<3)?$GIF_dis:3):2;<br /> $this->COL=($GIF_red>-1&&$GIF_grn>-1&&$GIF_blu>-1)?($GIF_red |($GIF_grn<<8)|($GIF_blu<<16)):-1;<br /><br /> for($i=0,$src_count=count($GIF_src);$i<$src_count;$i++){<br /> if(strToLower($GIF_mod)=="url"){<br /> $this->BUF[]=fread(fopen($GIF_src [$i],"rb"),filesize($GIF_src [$i]));<br /> }elseif(strToLower($GIF_mod)=="bin"){<br /> $this->BUF [ ]=$GIF_src [ $i ];<br /> }else{<br /> printf("%s: %s(%s)!",$this->VER,$this->ERR [ 'ERR02' ],$GIF_mod);<br /> exit(0);<br /> } <br /> if(substr($this->BUF[$i],0,6)!="GIF87a"&&substr($this->BUF [$i],0,6)!="GIF89a"){<br /> printf("%s: %d %s",$this->VER,$i,$this->ERR ['ERR01']);<br /> exit(0);<br /> } <br /> for($j=(13+3*(2<<(ord($this->BUF[$i]{10})&0x07))),$k=TRUE;$k;$j++){<br /> switch($this->BUF [$i]{$j}){<br /> case "!": <br /> if((substr($this->BUF[$i],($j+3),8))=="NETSCAPE"){<br /> printf("%s: %s(%s source)!",$this->VER,$this->ERR ['ERR03'],($i+1));<br /> exit(0);<br /> } <br /> break;<br /> case ";": <br /> $k=FALSE;<br /> break;<br /> } <br /> } <br /> } <br /> GIFEncoder::GIFAddHeader();<br /> for($i=0,$count_buf=count($this->BUF);$i<$count_buf;$i++){<br /> GIFEncoder::GIFAddFrames($i,$GIF_dly[$i]);<br /> } <br /> GIFEncoder::GIFAddFooter();<br /> } <br /> function GIFAddHeader(){<br /> $cmap=0;<br /> if(ord($this->BUF[0]{10})&0x80){<br /> $cmap=3*(2<<(ord($this->BUF [0]{10})&0x07));<br /> $this->GIF.=substr($this->BUF [0],6,7);<br /> $this->GIF.=substr($this->BUF [0],13,$cmap);<br /> $this->GIF.="!\377\13NETSCAPE2.0\3\1".GIFEncoder::GIFWord($this->LOP)."\0";<br /> } <br /> } <br /> function GIFAddFrames($i,$d){<br /> $Locals_str=13+3*(2 <<(ord($this->BUF[$i]{10})&0x07));<br /> $Locals_end=strlen($this->BUF[$i])-$Locals_str-1;<br /> $Locals_tmp=substr($this->BUF[$i],$Locals_str,$Locals_end);<br /> $Global_len=2<<(ord($this->BUF [0]{10})&0x07);<br /> $Locals_len=2<<(ord($this->BUF[$i]{10})&0x07);<br /> $Global_rgb=substr($this->BUF[0],13,3*(2<<(ord($this->BUF[0]{10})&0x07)));<br /> $Locals_rgb=substr($this->BUF[$i],13,3*(2<<(ord($this->BUF[$i]{10})&0x07)));<br /> $Locals_ext="!\xF9\x04".chr(($this->DIS<<2)+0).chr(($d>>0)&0xFF).chr(($d>>8)&0xFF)."\x0\x0";<br /> if($this->COL>-1&&ord($this->BUF[$i]{10})&0x80){<br /> for($j=0;$j<(2<<(ord($this->BUF[$i]{10})&0x07));$j++){<br /> if(ord($Locals_rgb{3*$j+0})==($this->COL>> 0)&0xFF&&ord($Locals_rgb{3*$j+1})==($this->COL>> 8)&0xFF&&ord($Locals_rgb{3*$j+2})==($this->COL>>16)&0xFF){<br /> $Locals_ext="!\xF9\x04".chr(($this->DIS<<2)+1).chr(($d>>0)&0xFF).chr(($d>>8)&0xFF).chr($j)."\x0";<br /> break;<br /> } <br /> } <br /> } <br /> switch($Locals_tmp{0}){<br /> case "!": <br /> $Locals_img=substr($Locals_tmp,8,10);<br /> $Locals_tmp=substr($Locals_tmp,18,strlen($Locals_tmp)-18);<br /> break;<br /> case ",": <br /> $Locals_img=substr($Locals_tmp,0,10);<br /> $Locals_tmp=substr($Locals_tmp,10,strlen($Locals_tmp)-10);<br /> break;<br /> } <br /> if(ord($this->BUF[$i]{10})&0x80&&$this->IMG>-1){<br /> if($Global_len==$Locals_len){<br /> if(GIFEncoder::GIFBlockCompare($Global_rgb,$Locals_rgb,$Global_len)){<br /> $this->GIF.=($Locals_ext.$Locals_img.$Locals_tmp);<br /> }else{<br /> $byte=ord($Locals_img{9});<br /> $byte|=0x80;<br /> $byte&=0xF8;<br /> $byte|=(ord($this->BUF [0]{10})&0x07);<br /> $Locals_img{9}=chr($byte);<br /> $this->GIF.=($Locals_ext.$Locals_img.$Locals_rgb.$Locals_tmp);<br /> } <br /> }else{<br /> $byte=ord($Locals_img{9});<br /> $byte|=0x80;<br /> $byte&=0xF8;<br /> $byte|=(ord($this->BUF[$i]{10})&0x07);<br /> $Locals_img {9}=chr($byte);<br /> $this->GIF.=($Locals_ext.$Locals_img.$Locals_rgb.$Locals_tmp);<br /> } <br /> }else{<br /> $this->GIF.=($Locals_ext.$Locals_img.$Locals_tmp);<br /> } <br /> $this->IMG=1;<br /> } <br /> function GIFAddFooter(){<br /> $this->GIF.=";";<br /> } <br /> function GIFBlockCompare($GlobalBlock,$LocalBlock,$Len){<br /> for($i=0;$i<$Len;$i++){<br /> if($GlobalBlock{3*$i+0}!=$LocalBlock{3*$i+0}||$GlobalBlock{3*$i+1}!=$LocalBlock{3*$i+1}||$GlobalBlock{3*$i+2}!=$LocalBlock{3*$i+2}){<br /> return(0);<br /> } <br /> } <br /> return(1);<br /> } <br /> function GIFWord($int){<br /> return(chr($int&0xFF).chr(($int>>8)&0xFF));<br /> } <br /> function GetAnimation(){<br /> return($this->GIF);<br /> } <br /><p>}
php生成动态验证码用法示例:
/*调用示例*/
session_start();<br />$checkCode='';<br />$chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPRSTUVWXYZ23456789';<br />for($i=0;$i<4;$i++){<br /> $checkCode.=substr($chars,mt_rand(0,strlen($chars)-1),1);<br />}<br />$_SESSION['code']=strtoupper($checkCode);// 记录session<br />ImageCode($checkCode,60);// 显示GIF动画