文档章节

仿百度GIF验证码 GIFEncoder 跳动验证码 随机背景色、颜色、字体、子大小、偏移、干扰线等

letwang
 letwang
发布于 2013/12/30 13:22
字数 990
阅读 621
收藏 8
<?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);
	}
}




© 著作权归作者所有

共有 人打赏支持
letwang
粉丝 171
博文 54
码字总数 81464
作品 1
南京
技术主管
私信 提问
加载中

评论(1)

kuaiyan312
kuaiyan312
写的很不错,收藏学习了。这里说明下,不知道是作者是不打算用session还是手误。超全局的$_SESSION这个地方,没有明白啊!哈哈
网上几种常见校验码图片分析

前几天受刺激了,准备把CSDN的校验码图片修改。就上网找了一些参考示例。和分析了一些校验码的功能。不敢独享,整理到一起,跟大家分享。 至于CSDN新的校验码写法,不是这里面的任何一种。也...

晨曦之光
2012/03/09
213
0
自己写了一个php验证码类,验证码可以正常显示,说明已经生成,但是通过属性值获取不到验证码,为空。

/* 问题:验证码可以正常显示,说明验证码已经生成(分别是$code和$gbkcode),但是通过属性值获取不到验证码,为空。 return $this->code; 为空? 求解............. */ width=$width; $thi...

刘伟伟
2012/07/27
1K
2
PHP生成验证码--Micoolcoder

多功能自定义PHP生成验证码 新增伪静态案例 支持自定义参数说明: 第一个参数 CS:简体中文 CT:繁体中文 E:大小英文 e:小写英文 D:数字 Ee:大小写英文 EeD:大小英文数字 ED:大写数字 eD:小写数...

Micool
2012/07/13
3.1K
0
动态 Web 校验码图片生成--XVcode

XVcode,Web 动态验证码图片生成工具,用于生成随机验证码图片及返回验证码。以随机圆圈为干扰背景,增加随机前后景透明度,并提供3种gif动态图。 PngGenerator : GifGenerator: Gif2Generat...

PoRui
2016/10/18
3.1K
4
Windows 8应用实例解析 - WinRT下创建GIF动画(Flipflop)

在Windows Store中下载了一个有意思的应用,叫做Flipflop(http://apps.microsoft.com/windows/app/flipflop/99c01512-fe4f-4d1a-872e-eb9fd6638ff4),该应用允许用户创建翻页式动画效果(Flip...

冷秋寒
06/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

EOS docker开发环境

使用eos docker镜像是部署本地EOS开发环境的最轻松愉快的方法。使用官方提供的eos docker镜像,你可以快速建立一个eos开发环境,可以迅速启动开发节点和钱包服务器、创建账户、编写智能合约....

汇智网教程
今天
7
0
《唐史原来超有趣》的读后感优秀范文3700字

《唐史原来超有趣》的读后感优秀范文3700字: 作者:花若离。我今天分享的内容《唐史原来超有趣》这本书的读后感,我将这本书看了一遍之后就束之高阁了,不过里面的内容一直在在脑海中回放,...

原创小博客
今天
13
0
IC-CAD Methodology知识图谱

CAD (Computer Aided Design),计算机辅助设计,指利用计算机及其图形设备帮助设计人员进行设计工作,这个定义同样可以用来近似描述IC公司CAD工程师这个岗位的工作。 早期IC公司的CAD岗位最初...

李艳青1987
今天
14
0
CompletableFuture get方法一直阻塞或抛出TimeoutException

问题描述 最近刚刚上线的服务突然抛出大量的TimeoutException,查询后发现是使用了CompletableFuture,并且在执行future.get(5, TimeUnit.SECONDS);时抛出了TimeoutException异常,导致接口响...

xiaolyuh
今天
8
0
dubbo 搭建与使用

官网:http://dubbo.apache.org/en-us/ 一,安装监控中心(可以不安装) admin管理控制台,monitor监控中心 下载 bubbo ops 这个是新版的,需要node.js环境,我没有就用老版的了...

小兵胖胖
今天
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部