浏览 4134 次
锁定老帖子 主题:PHP验证框
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-12-23
接触PHP一个星期了,boss要写一个图片验证框。在网上查了很多的资料,总结后得到如下最终的代码。以下代码生成的验证码有干扰条,干扰像素,字体旋转等。如果有不足的地方请回帖。 <?php header("Pragma: no-cache"); header("Cache-Control: max-age=1, s-maxage=1, no-cache, must-revalidate"); session_start(); unset ($_SESSION['validate']); $strnum = 8; //产生密码的位数 $str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; //显示的字符范围 $font_file = 'Fregne Myriad v2.ttf';//指定字体文件 $disturbpiont = true; //是否显示干扰素 $disturbpiontnum = 600; //干扰素的点的数目 $disturbline = true; //是否有干扰条 $disturblinenum = 8; //干扰条的数目 $l = strlen($str); $randStr = array (); $validate; for ($i = 0; $i < $strnum; ++ $i) { $randStr[$i] = $str[rand(0, $l)]; } for ($i = 0; $i < $strnum; ++ $i) { if ($randStr[$i] == '') $randStr[$i] = '*'; $validate = $validate . $randStr[$i]; } function RgbToHsv($R, $G, $B) { $tmp = min($R, $G); $min = min($tmp, $B); $tmp = max($R, $G); $max = max($tmp, $B); $V = $max; $delta = $max - $min; if ($max != 0) $S = $delta / $max; // s else { $S = 0; return; } if ($R == $max) $H = ($G - $B) / $delta; // between yellow & magenta else if ($G == $max) $H = 2 + ($B - $R) / $delta; // between cyan & yellow else $H = 4 + ($R - $G) / $delta; // between magenta & cyan $H *= 60; // degrees if ($H < 0) $H += 360; return array ( $H, $S, $V ); } function HsvToRgb($H, $S, $V) { if ($S == 0) { // achromatic (grey) $R = $G = $B = $V; return; } $H /= 60; // sector 0 to 5 $i = floor($H); $f = $H - $i; // factorial part of h $p = $V * (1 - $S); $q = $V * (1 - $S * $f); $t = $V * (1 - $S * (1 - $f)); switch ($i) { case 0 : $R = $V; $G = $t; $B = $p; break; case 1 : $R = $q; $G = $V; $B = $p; break; case 2 : $R = $p; $G = $V; $B = $t; break; case 3 : $R = $p; $G = $q; $B = $V; break; case 4 : $R = $t; $G = $p; $B = $V; break; default : // case 5: $R = $V; $G = $p; $B = $q; break; } return array ( $R, $G, $B ); } $size = 30; $width = $size * $strnum +10; $height = $size +10; $degrees = array (); for ($i = 0; $i < $strnum; ++ $i) { $degrees[$i] = rand(0, 35); } // 生成数字旋转角度 for ($i = 0; $i < $strnum; ++ $i) { if (rand() % 2); else $degrees[$i] = - $degrees[$i]; } $image = imagecreatetruecolor($size, $size); // 数字图片画布 $validatepic = imagecreatetruecolor($width, $height); // 最终验证码画布 $back = imagecolorallocate($image, 255, 255, 255); // 背景色 $border = imagecolorallocate($image, 0, 0, 0); // 边框 imagefilledrectangle($validatepic, 0, 0, $width, $height, $back); // 画出背景色 // 数字颜色 for ($i = 0; $i < $strnum; ++ $i) { // 考虑为使字符容易看清使用颜色较暗的颜色 $temp = RgbToHsv(rand(0, 255), rand(0, 255), rand(0, 255)); if ($temp[2] > 60) $temp[2] = 60; $temp = HsvToRgb($temp[0], $temp[1], $temp[2]); $textcolor[$i] = imagecolorallocate($image, $temp[0], $temp[1], $temp[2]); } for ($i = 0; $i < $disturbpiontnum && $disturbpiont; ++ $i) //加入干扰象素 { $randpixelcolor = ImageColorallocate($validatepic, rand(0, 255), rand(0, 255), rand(0, 255)); imagesetpixel($validatepic, rand(1, $width -1), rand(1, $height -1), $randpixelcolor); } // 干扰线使用颜色较明亮的颜色 $temp = RgbToHsv(rand(0, 255), rand(0, 255), rand(0, 255)); if ($temp[2] < 200) $temp[2] = 255; $temp = HsvToRgb($temp[0], $temp[1], $temp[2]); $randlinecolor = imagecolorallocate($image, $temp[0], $temp[1], $temp[2]); // 画干扰线 for ($i = 0; $i < $disturblinenum && $disturbline; $i++) imageline($validatepic, rand(1, 239), rand(1, 39), rand(1, 239), rand(1, 39), $randpixelcolor); for ($i = 0; $i < $strnum; ++ $i) { $image = imagecreatetruecolor($size, $size); // 刷新画板 imagefilledrectangle($image, 0, 0, $size, $size, $back); // 画出背景色 imagefttext($image, 13, 0, 5, 20, $textcolor[$i], $font_file, $randStr[$i]); $image = imagerotate($image, $degrees[$i], $back); imagecolortransparent($image, $back); imagecopymerge($validatepic, $image, 5 + 30 * $i, 5, 0, 0, imagesx($image), imagesy($image), 100); } imagerectangle($validatepic, 0, 0, $width -1, $height -1, $border); // 画出边框 header('Content-type: image/png'); imagepng($validatepic); imagedestroy($validatepic); imagedestroy($image); $_SESSION['code'] = $validate;//将验证码存入session,如果实际应用,请md5. ?> 字体文件和该文件放在同一目录下即可,如果不是请设置 $font_file 需要设置背景颜色请修改 $back = imagecolorallocate($image, 255, 255, 255); // 背景色 显示图框的大小会随着设置显示的字符数变化。使用起来还是比较方便的。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-12-25
以下内容节选自《PHP Web2.0开发实战》 老外写国人译的书
可以使用PEAR(PHP扩展与应用库)提供的Text_CAPTCHA组件来生成CAPTCHA图象。 先安装:可以下载,也可用pear命令 pear install Text_Password pear install -f Text_CAPTCHA pear install -f Image_Text 这个包依赖于另外两个,我试了一下,主要是生成随机的字符用的 还需要一个字体文件,后缀是ttf,网上很多, // 以下是createImage.php include(Text_CAPTCHA文件); //如果include路径已指向pear目录,可以没有这句话 $captcha = Text_CAPTCHA::factory('Image'); //生成对象先 //以下依次是大小,字库文件的路径,字库文件名 $opts = array('font_size' => 20, 'font_path' => Zend_Registry::get('config')->paths->data, 'font_file' => 'VeraBd.ttf'); $phare = 自定义一个随机数; $captcha->init(120, 60, $phrase, $opts); //120和60是生成图片的宽和高 //这里我选择png图片,随意,也可用jpg header('Content-type: image/png'); echo $captcha->getCAPTCHAAsPng(); //以下是test.html <img src="createImage.php"> 是不是很简单? |
|
返回顶楼 | |