您的位置:首页 > 编程语言 > PHP开发

Zend_Captcha 验证码研究

2012-05-16 18:54 405 查看
复制PHP内容到剪贴板
PHP代码:
private $codeSession; //定义一个全局 Zend_Session_Namespace

$this->codeSession = new Zend_Session_Namespace('code'); //在默认构造函数里实例化

$captcha = new Zend_Captcha_Image(array('font'=>'/images/Faktos.ttf',

//字体文件路径

'fontsize'=>24,

'imgdir'=>'images/captcha',
//验证码图片存放位置

'session'=>$this->codeSession,

'width'=>200,

'height'=>50,

'wordlen'=>5 ));
//字母数

$captcha->setGcFreq(3);//设置删除生成的旧的验证码图片的随机几率

$captcha->generate();
//生成图片

$this->codeSession->code=$captcha->getWord();
//获取当前生成的验证字符串

echo $this->codeSession->code;

Faktos.ttf 这是字体文件. 换成你的也可以.注意路径.

出来的结果如下



并且实现了验证码字符 存放在了session 中.

现在问题, 怎么 降噪,上面的 黑色斑点太多了...

(1)编辑 Zend/Captcha/Image.php

两个地方同时改动红色数字 降低躁点,查找 imagefilledellipse

// generate noise

for ($i=0; $i<100; $i++) {

imagefilledellipse($img, mt_rand(0,$w), mt_rand(0,$h), 2, 2, $text_color);

}

或者

(2)

PHP代码:
class ImgCode extends Zend_Captcha_Image

{

protected function _generateImage($id, $word)

{

if (!extension_loaded("gd")) {

require_once 'Zend/Form/Exception.php';

throw new Zend_Form_Exception("Image CAPTCHA requires GD extension");

}

if (!function_exists("imagepng")) {

require_once 'Zend/Form/Exception.php';

throw new Zend_Form_Exception("Image CAPTCHA requires PNG support");

}

if (!function_exists("imageftbbox")) {

require_once 'Zend/Form/Exception.php';

throw new Zend_Form_Exception("Image CAPTCHA requires FT fonts support");

}

$font = $this->getFont();

if (empty($font)) {

require_once 'Zend/Form/Exception.php';

throw new Zend_Form_Exception("Image CAPTCHA requires font");

}

@header("Content-Type:image/png"); //这是我添加的

$w = $this->getWidth();

$h = $this->getHeight();

$fsize = $this->getFontSize();

$img_file = $this->getImgDir() . $id . $this->getSuffix();

$img= imagecreatetruecolor($w, $h);

$text_color = imagecolorallocate($img, 0, 0, 0);

$bg_color = imagecolorallocate($img, 255, 255, 255);

imagefilledrectangle($img, 0, 0, $w-1, $h-1, $bg_color);

$textbox = imageftbbox($fsize, 0, $font, $word);

$x = ($w - ($textbox[2] - $textbox[0])) / 2;

$y = ($h - ($textbox[7] - $textbox[1])) / 2;

imagefttext($img, $fsize, 0, $x, $y, $text_color, $font, $word);

// generate noise

//for ($i=0; $i<100; $i++) {

// imagefilledellipse($img, mt_rand(0,$w), mt_rand(0,$h), 2, 2, $text_color);

//}

for($i=0; $i<5; $i++) {

imageline($img, mt_rand(0,$w), mt_rand(0,$h), mt_rand(0,$w), mt_rand(0,$h), $text_color);

}

// transformed image

$img2 = imagecreatetruecolor($w, $h);

$bg_color = imagecolorallocate($img2, 255, 255, 255);

imagefilledrectangle($img2, 0, 0, $w-1, $h-1, $bg_color);

// apply wave transforms

$freq1 = $this->_randomFreq();

$freq2 = $this->_randomFreq();

$freq3 = $this->_randomFreq();

$freq4 = $this->_randomFreq();

$ph1 = $this->_randomPhase();

$ph2 = $this->_randomPhase();

$ph3 = $this->_randomPhase();

$ph4 = $this->_randomPhase();

$szx = $this->_randomSize();

$szy = $this->_randomSize();

for ($x = 0; $x < $w; $x++) {

for ($y = 0; $y < $h; $y++) {

$sx = $x + (sin($x*$freq1 + $ph1) + sin($y*$freq3 + $ph3)) * $szx;

$sy = $y + (sin($x*$freq2 + $ph2) + sin($y*$freq4 + $ph4)) * $szy;

if ($sx < 0 || $sy < 0 || $sx >= $w - 1 || $sy >= $h - 1) {

continue;

} else {

$color= (imagecolorat($img, $sx, $sy) >> 16) & 0xFF;

$color_x= (imagecolorat($img, $sx + 1, $sy) >> 16) & 0xFF;

$color_y= (imagecolorat($img, $sx, $sy + 1) >> 16) & 0xFF;

$color_xy = (imagecolorat($img, $sx + 1, $sy + 1) >> 16) & 0xFF;

}

if ($color == 255 && $color_x == 255 && $color_y == 255 && $color_xy == 255) {

// ignore background

continue;

} elseif ($color == 0 && $color_x == 0 && $color_y == 0 && $color_xy == 0) {

// transfer inside of the image as-is

$newcolor = 0;

} else {

// do antialiasing for border items

$frac_x= $sx-floor($sx);

$frac_y= $sy-floor($sy);

$frac_x1 = 1-$frac_x;

$frac_y1 = 1-$frac_y;

$newcolor = $color* $frac_x1 * $frac_y1

+ $color_x* $frac_x* $frac_y1

+ $color_y* $frac_x1 * $frac_y

+ $color_xy * $frac_x* $frac_y;

}

imagesetpixel($img2, $x, $y, imagecolorallocate($img2, $newcolor, $newcolor, $newcolor));

}

}

// generate noise

//for ($i=0; $i<100; $i++) {

//imagefilledellipse($img2, mt_rand(0,$w), mt_rand(0,$h), 2, 2, $text_color);

//}

//for ($i=0; $i<5; $i++) {

// imageline($img2, mt_rand(0,$w), mt_rand(0,$h), mt_rand(0,$w), mt_rand(0,$h), $text_color);

//}

imagepng($img2); //这里我去掉了 $img_file 这个参数

imagedestroy($img);

imagedestroy($img2);

}

}


只是继承了 Zend_Captcha_Image并 重写了里面的方法, 只是把他的方法复制过来.然后 注释了几行.加了 header

把 ImgCode 这个类放在 modules 目录里就可以了

Zend居然每刷新一次 就生成一张图片 并且存放到 $imgdir 下面

在这里设定一个图片数量 超过限制就自动删除。 如上代码所示 $captcha->setGcFreq(3)

另外需要修改 protected function _gc() 函数为:

protected function _gc()

{

//$expire = time() - $this->getExpiration();

$expire = time();

echo $this->getExpiration();

foreach (new DirectoryIterator($this->getImgDir()) as $file) {

if (!$file->isDot() && !$file->isDir()) {

if ($file->getMTime() < $expire) {

unlink($file->getPathname());

}

}

}

}

PHP代码:
$captcha = new ImgCode(array('font'=>'/images/Faktos.ttf',//字体路径

'fontsize'=>字体大小,

'session'=>$this->codeSession,//存放的 session 对象

'width'=>宽,

'height'=>高,

'wordlen'=>字符数));

$id=$captcha->generate();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: