仿百度GIF验证码 GIFEncoder 跳动验证码 随机背景色、颜色、字体、子大小、偏移、干扰线等
博客专区 > let 的博客 > 博客详情
仿百度GIF验证码 GIFEncoder 跳动验证码 随机背景色、颜色、字体、子大小、偏移、干扰线等
let 发表于4年前
仿百度GIF验证码 GIFEncoder 跳动验证码 随机背景色、颜色、字体、子大小、偏移、干扰线等
  • 发表于 4年前
  • 阅读 595
  • 收藏 7
  • 点赞 1
  • 评论 2
摘要: 仿百度GIF验证码 GIFEncoder 跳动验证码 随机背景色、颜色、字体、子大小、偏移、干扰线等
<?php
session_start ();

$SEESIN ['captcha'] = mt_rand ( 1111, 9999 );//py by:http://my.oschina.net/cart/

$imagedata = generateGif ( $SEESIN ['captcha'] );
$delay = array(20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20);//每帧动画延迟的时间

$gif = new GIFEncoder ( $imagedata,  $delay);
header ( 'Content-type:image/gif' );
// var_dump($SEESIN);
echo $gif->GetAnimation ();

function generateGif($str, $length = 4, $width = 60, $height = 22) {
	$width = ($length * 10 + 10) > $width ? $length * 10 + 10 : $width;
	// 生成一个32帧的GIF动画
	for($i = 0; $i < 32; $i ++) {
		ob_start ();
		$image = imagecreatetruecolor ( $width, $height );
		// 背景色
		imagefill ( $image, 0, 0, imagecolorallocate ( $image, 255, 255, 255 ) );
		// 设定文字随机颜色
		$colorList = array (
				imagecolorallocate ( $image, 15, 73, 210 ),
				imagecolorallocate ( $image, 0, 64, 0 ) 
		);
		//设定文字随机字体
		$fontList = array(
				'public/font/msyhbd.ttf',
				'public/font/simsun.ttc',
				'public/font/arial.ttf'
		);
		if ($i > 0) { // 屏蔽第一帧
			$left = 10;
			$top = 15;
			for($k = 0; $k < $length; $k ++) {
				imagettftext ( $image, 12, mt_rand (0, 10), ($left * $k) + mt_rand ( 0, 15 ), $top + mt_rand ( 0, 10 ), $colorList[array_rand($colorList)], $fontList[array_rand($fontList)], mb_substr ( $str, $k, 1 ) );
			}
		}
		// 添加点点
		for($k = 0; $k < 20; $k ++) {
			imagesetpixel ( $image, mt_rand () % 50, mt_rand () % 40, $colorList[array_rand($colorList)] );
		}
		// 添加干扰线
		for($k = 0; $k < 3; $k ++) {
			if (mt_rand ( 0, 1 )) {
				// 直线
				imageline ( $image, mt_rand ( 0, $width ), mt_rand ( 0, $height ), mt_rand ( 0, $width ), mt_rand ( 0, $height ), $colorList[array_rand($colorList)] );
			} else {
				// 弧线
				$w = mt_rand ( 0, $width );
				$h = mt_rand ( 0, $height );
				imagearc ( $image, $width - floor ( $w / 2 ), floor ( $h / 2), $w, $h, mt_rand ( 90, 180 ), mt_rand ( 180, 270 ), $colorList[array_rand($colorList)] );
			}
		}
		imagegif ( $image );
		imagedestroy ( $image );
		$imagedata [] = ob_get_contents ();
		ob_clean ();
		++ $i;
	}
	return $imagedata;
}

class GIFEncoder {
	var $GIF = "GIF89a"; /* GIF header 6 bytes */
	var $VER = "GIFEncoder V2.06"; /* Encoder version */
	var $BUF = Array ();
	var $LOP = 0;
	var $DIS = 2;
	var $COL = - 1;
	var $IMG = - 1;
	var $ERR = Array (
			'ERR00' => "Does not supported function for only one image!",
			'ERR01' => "Source is not a GIF image!",
			'ERR02' => "Unintelligible flag ",
			'ERR03' => "Could not make animation from animated GIF source" 
	);
	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') {
		if (! is_array ( $GIF_src ) && ! is_array ( $GIF_tim )) {
			printf ( "%s: %s", $this->VER, $this->ERR ['ERR00'] );
			exit ( 0 );
		}
		$this->LOP = ($GIF_lop > - 1) ? $GIF_lop : 0;
		$this->DIS = ($GIF_dis > - 1) ? (($GIF_dis < 3) ? $GIF_dis : 3) : 2;
		$this->COL = ($GIF_red > - 1 && $GIF_grn > - 1 && $GIF_blu > - 1) ? ($GIF_red | ($GIF_grn << 8) | ($GIF_blu << 16)) : - 1;
		
		for($i = 0, $src_count = count ( $GIF_src ); $i < $src_count; $i ++) {
			if (strToLower ( $GIF_mod ) == "url") {
				$this->BUF [] = fread ( fopen ( $GIF_src [$i], "rb" ), filesize ( $GIF_src [$i] ) );
			} elseif (strToLower ( $GIF_mod ) == "bin") {
				$this->BUF [] = $GIF_src [$i];
			} else {
				printf ( "%s: %s ( %s )!", $this->VER, $this->ERR ['ERR02'], $GIF_mod );
				exit ( 0 );
			}
			if (substr ( $this->BUF [$i], 0, 6 ) != "GIF87a" && substr ( $this->BUF [$i], 0, 6 ) != "GIF89a") {
				printf ( "%s: %d %s", $this->VER, $i, $this->ERR ['ERR01'] );
				exit ( 0 );
			}
			for($j = (13 + 3 * (2 << (ord ( $this->BUF [$i] {10} ) & 0x07))), $k = TRUE; $k; $j ++) {
				switch ($this->BUF [$i] {$j}) {
					case "!" :
						if ((substr ( $this->BUF [$i], ($j + 3), 8 )) == "NETSCAPE") {
							printf ( "%s: %s ( %s source )!", $this->VER, $this->ERR ['ERR03'], ($i + 1) );
							exit ( 0 );
						}
						break;
					case ";" :
						$k = FALSE;
						break;
				}
			}
		}
		GIFEncoder::GIFAddHeader ();
		for($i = 0, $count_buf = count ( $this->BUF ); $i < $count_buf; $i ++) {
			GIFEncoder::GIFAddFrames ( $i, $GIF_dly [$i] );
		}
		GIFEncoder::GIFAddFooter ();
	}
	function GIFAddHeader() {
		$cmap = 0;
		
		if (ord ( $this->BUF [0] {10} ) & 0x80) {
			$cmap = 3 * (2 << (ord ( $this->BUF [0] {10} ) & 0x07));
			
			$this->GIF .= substr ( $this->BUF [0], 6, 7 );
			$this->GIF .= substr ( $this->BUF [0], 13, $cmap );
			$this->GIF .= "!\377\13NETSCAPE2.0\3\1" . GIFEncoder::GIFWord ( $this->LOP ) . "\0";
		}
	}
	function GIFAddFrames($i, $d) {
		$Locals_str = 13 + 3 * (2 << (ord ( $this->BUF [$i] {10} ) & 0x07));
		
		$Locals_end = strlen ( $this->BUF [$i] ) - $Locals_str - 1;
		$Locals_tmp = substr ( $this->BUF [$i], $Locals_str, $Locals_end );
		
		$Global_len = 2 << (ord ( $this->BUF [0] {10} ) & 0x07);
		$Locals_len = 2 << (ord ( $this->BUF [$i] {10} ) & 0x07);
		
		$Global_rgb = substr ( $this->BUF [0], 13, 3 * (2 << (ord ( $this->BUF [0] {10} ) & 0x07)) );
		$Locals_rgb = substr ( $this->BUF [$i], 13, 3 * (2 << (ord ( $this->BUF [$i] {10} ) & 0x07)) );
		
		$Locals_ext = "!\xF9\x04" . chr ( ($this->DIS << 2) + 0 ) . chr ( ($d >> 0) & 0xFF ) . chr ( ($d >> 8) & 0xFF ) . "\x0\x0";
		
		if ($this->COL > - 1 && ord ( $this->BUF [$i] {10} ) & 0x80) {
			for($j = 0; $j < (2 << (ord ( $this->BUF [$i] {10} ) & 0x07)); $j ++) {
				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) {
					$Locals_ext = "!\xF9\x04" . chr ( ($this->DIS << 2) + 1 ) . chr ( ($d >> 0) & 0xFF ) . chr ( ($d >> 8) & 0xFF ) . chr ( $j ) . "\x0";
					break;
				}
			}
		}
		switch ($Locals_tmp {0}) {
			case "!" :
				$Locals_img = substr ( $Locals_tmp, 8, 10 );
				$Locals_tmp = substr ( $Locals_tmp, 18, strlen ( $Locals_tmp ) - 18 );
				break;
			case "," :
				$Locals_img = substr ( $Locals_tmp, 0, 10 );
				$Locals_tmp = substr ( $Locals_tmp, 10, strlen ( $Locals_tmp ) - 10 );
				break;
		}
		if (ord ( $this->BUF [$i] {10} ) & 0x80 && $this->IMG > - 1) {
			if ($Global_len == $Locals_len) {
				if (GIFEncoder::GIFBlockCompare ( $Global_rgb, $Locals_rgb, $Global_len )) {
					$this->GIF .= ($Locals_ext . $Locals_img . $Locals_tmp);
				} else {
					$byte = ord ( $Locals_img {9} );
					$byte |= 0x80;
					$byte &= 0xF8;
					$byte |= (ord ( $this->BUF [0] {10} ) & 0x07);
					$Locals_img {9} = chr ( $byte );
					$this->GIF .= ($Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp);
				}
			} else {
				$byte = ord ( $Locals_img {9} );
				$byte |= 0x80;
				$byte &= 0xF8;
				$byte |= (ord ( $this->BUF [$i] {10} ) & 0x07);
				$Locals_img {9} = chr ( $byte );
				$this->GIF .= ($Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp);
			}
		} else {
			$this->GIF .= ($Locals_ext . $Locals_img . $Locals_tmp);
		}
		$this->IMG = 1;
	}
	function GIFAddFooter() {
		$this->GIF .= ";";
	}
	function GIFBlockCompare($GlobalBlock, $LocalBlock, $Len) {
		for($i = 0; $i < $Len; $i ++) {
			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}) {
				return (0);
			}
		}
		return (1);
	}
	function GIFWord($int) {
		return (chr ( $int & 0xFF ) . chr ( ($int >> 8) & 0xFF ));
	}
	function GetAnimation() {
		return ($this->GIF);
	}
}




共有 人打赏支持
粉丝 138
博文 66
码字总数 75584
评论 (2)
kuaiyan312
写的很不错,收藏学习了。这里说明下,不知道是作者是不打算用session还是手误。超全局的$_SESSION这个地方,没有明白啊!哈哈
let

引用来自“kuaiyan312”的评论

写的很不错,收藏学习了。这里说明下,不知道是作者是不打算用session还是手误。超全局的$_SESSION这个地方,没有明白啊!哈哈

$SEESIN ['captcha'] 没有看到么?
哈哈 或者$SEESIN 我只是害羞的赋值了一下,抛砖引玉啊
×
let
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: