PHP图形验证码程序

7/1/2009来源:PHP技巧人气:10132

最近经常有人问我这个Blog中的图形验证码是如何做的.下面是这个php图形验证码的源程序.

欢迎指正.

class.image.php

/*
===========================================================   
    class.image.php    Zhu Weiwei
    Copyright © 2006-2008
    http://www.cncmm.com China. All Rights Reserved.
===========================================================
*/
class Image
{
    PRivate $img;
    private $width;
    private $height;
    private $color;
    private $font;
    private $mime="image/jpeg";

    /* 1,GIF  2,JPEG  3,PNG */
    private $type=2;
    private $angle=0;
    private $text;
    private $textW;
    private $textH;
    private $size=5;
    private $tcolor;

     
    function __construct($w="100", $h="50"){
        $this->width=$w;
        $this->height=$h;
    }
   
    function create() {
        if ($this->type != 1 && function_exists('imagecreatetruecolor')) {
            // 本函数不能用于 GIF 文件格式
            // 本函数需要 GD 2.0.1 或更高版本。
            // 返回一个图像标识符,代表了一幅大小为 x_size 和 y_size 的黑色图像
            $this->img=imagecreatetruecolor($this->width,$this->height);
        }else {
            $this->img=imagecreate($this->width,$this->height);
        }       
    }

    /*
    * 1=GIF     2=JPG
    * 3=PNG
    */
    function createFromFile($f){
        $imgInfo=getimagesize($f);
        $this->type=$imgInfo[2];

        switch($this->type){
        case 1:
            $this->loadGifFile($f);
            break;
           
        case 2:
            $this->loadJpegFile($f);
            break;
           
        case 3:
            $this->loadPngFile($f);
            break;
           
        default:
            die("This Image Type Not Support loadimage !");
            exit();
        }
    }
   
    function loadGifFile($f){
        // 1.6  -- 2.0.28
        //二者之间版本的 GD 库时本函数不可用
        $this->img=imagecreatefromgif($f ) or die("Load Gif picture error!") ;
        $this->width=imagesx($this->img); 
        $this->height=imagesy($this->img);  
        $this->mime="image/gif";
        $this->type=1;
    }
   
   
    function loadJpegFile($f){
        //JPEG 支持仅在 PHP 与 GD-1.8 或更高版本一起编译时可用
        $this->img=imagecreatefromjpeg($f) or die("Load Jpeg picture error!") ;
        $this->width=imagesx($this->img); 
        $this->height=imagesy($this->img);  
        $this->mime="image/jpeg";
        $this->type=2;
    }
   
   
    function loadPngFile($f){
        $this->img=imagecreatefrompng($f )  or die("Load Png picture error!") ;
        $this->width=imagesx($this->img); 
        $this->height=imagesy($this->img);  
        $this->mime="image/png";
        $this->type=3;
    }

     
   
    function setBackgroundColor($r, $g, $b){
        ## 用color 颜色填充了的矩形
        ## 其左上角坐标为 x1,y1
        ## 右下角坐标为 x2,y2
        ## 0, 0 是图像的最左上角
        $color =imagecolorallocate($this->img, $r, $g, $b);
        return imagefilledrectangle($this->img, 0, 0, $this->width, $this->height, $color);
    }
   
    function setColor($r, $g, $b){
        $this->color=imagecolorallocate($this->img, $r, $g, $b);
        return (-1 == $this->color) ? (false) : ($this->color);
    }
   
   
    function setTextColor($r, $g, $b){
        $this->tcolor=imagecolorallocate($this->img, $r, $g, $b);
        return (-1 == $this->tcolor) ? (false) : ($this->tcolor);
    }
   
     
    function setText($t){
        $this->text=$t;
    }

    function waterMark($r, $g, $b, $alpha){
        $this->tcolor=imagecolorclosestalpha($this->img, $r, $g, $b, $alpha);
    }
     
   
    function setFontFile($f){ 
        $this->font=$f;
    }
   
    function addTrueTypeText($xoffset,$yoffset){
        #$x=( ( $this->width - $this->textW - 10) > 0) ? ($this->width - $this->textW - 10) : (0) ;
        #$y=( ( $this->height-10) >  0) ? ($this->height-10) : ($this->height);
        // 用 TrueType 字体向图像写入文本
        // **x,y 坐标是字符串左下角坐标,整幅图像的左上角为 0,0
        imagettftext($this->img,
            $this->size,
            $this->angle,
            $xoffset,
            $yoffset,
            $this->tcolor,
            $this->font,
            $this->text);
    }

    function addText() {
        // http://www.devdao.com/ 用 color 颜色将字符串 s 画到 image
        // **x,y 坐标是字符串左上角坐标,整幅图像的左上角为 0,0
        // 如果font 是 1,2,3,4 或 5,则使用内置字体。
        imagestring ($this->img, $font, $x, $y, $this->text, $this->tcolor);       
    }
   
    function setSize($s){
        $this->size=$s;
    }
   
    function setAngle($a){
        $this->angle=$a;
    }     
   
   
    function setWidth($w){
        $this->width=$w;
    }
   
   
    function setHeight($h){
        $this->height=$h;
    }
   
   
    function getWidth(){
        return $this->width;
    }
   
   
    function getHeight(){
        return $this->height;
    }

    function setPixel($x,$y,$color){
        return imagesetpixel($this->img, $x, $y, $color);
    }

    function setLine($x1,$y1,$x2,$y2,$color){
        return imageline($this->img, $x1, $y1, $x2, $y2, $color);
    }
   
    function createImageFile($f="default"){
        if( !empty($f) ){
            switch($this->type){
                case 1:
                imagegif($this->img, $f.".gif",80);
                break;
               
                case 2:
                imagejpeg($this->img, $f.".jpg" , 80);
                break;
               
                case 3:
                imagepng($this->img, $f.".png", 80);
                break;
               
                default:
                die("This Image Type Not Support create !");
                exit();
            }
            imagedestroy($this->img);
        }
    }

                                       
    function show(){
        header("Content-type: ".$this->mime); 
        switch($this->type){
            case 1:
            imagegif($this->img);
            break;
           
            case 2:
            imagejpeg($this->img);
            break;
           
            case 3:
            imagepng($this->img);
            break;
           
            default:
            die("This Image Type Not Support  show !");
            exit();
        }
        imagedestroy($this->img);
    }
     
    /* Zoom Out Picture */
    function roomOut($maxW, $maxH){
        $WW=(($maxW) and ($this->width > $maxW));
        $HH=(($maxH) and ($this->height > $maxH));
       
        if($WW or $HH){
            if($WW){
                $wRatio =$maxW / $this->width;
                $wResize=true;
            }
            if($HH){
                $hRatio =$maxH / $this->height;
                $hResize=true;
            }
           
            if($wResize and $hResize){
                if($wRatio < $hRatio){
                    $ratio=$wRatio;
                }else{
                    $ratio=$hRatio;
                }
            }elseif($wResize){
                $ratio=$wRatio;
            }elseif($hResize){
                $ratio=$hRatio;
            }
        }else{
            $ratio=1;
        }
       
        $newWidth=$this->width * $ratio; 
        $newHeight=$this->height * $ratio;
       
        if(function_exists("imagecopyresampled")){
            $newimg=imagecreatetruecolor($newWidth, $newHeight);
            imagecopyresampled($newimg, $this->img, 0, 0, 0, 0, $newWidth, $newHeight, $this->width, $this->height);
        }else{
            $newimg=imagecreate($newWidth, $newHeight);
            imagecopyresized($newimg, $this->img, 0, 0, 0, 0, $newWidth, $newHeight, $this->width, $this->height);
        }
        $this->img=$newimg;        
        $this->width=  $newWidth;
        $this->height=$newHeight;
    }
}
imgverifycode.php

/*
===========================================================   
    imgverifycode.php    Zhu Weiwei
    Copyright © 2006-2008
    http://www.cncmm.com China. All Rights Reserved.
===========================================================
*/
<?php
require('class.image.php');
# char number
$n = 4;
#font size
$s = 18;
#font padding
$p = 5;
#font angle -a,a
$a = 15;
#image width
$w = ($s+$p)*$n+$p;
#image height;
$h = intval($s*1.5);

$c = ($h + $s)/2;
$o = abs($h-$s-2*$p)/2;
$r = 1;

$str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
#$str = '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz';
#$str = '0123456789';

$len = strlen($str)-1;
$code = '';


$im = new Image($w,$h);
$im->create();
$im->setBackgroundColor( mt_rand(0xdd,0xff), mt_rand(0xdd,0xff), mt_rand(0xdd,0xff) );

$im->setSize( $s );

for($i=$p; $i<$w-$p; $i=$i+$s+$p){
    $char = $str{mt_rand(0,$len)};
    $code = $code.$char;
   
    $im->setFontFile($CFG->dirroot.'/font/'.mt_rand(2,5).'.ttf');
   
    $im->setText( $char );
    $im->setAngle( mt_rand(-$a,$a) );
    $im->setTextColor(mt_rand(0x0,0x66),mt_rand(0x0,0x66),mt_rand(0x0,0x66) );
    $im->addTrueTypeText($i,mt_rand($c-$o,$c+$o));
    for($j=0; $j<8*$r; $j++){
        $xs = mt_rand($i-$s/2+$p,$i+$s/2-$p);
        $ys = mt_rand($p,$h-$p);
        $color = $im->setColor(mt_rand(0x0,0x66),mt_rand(0x0,0x66),mt_rand(0x0,0x66));
        $im->setLine( $xs, $ys, $xs+mt_rand(-$s/2,$s/2), $ys+mt_rand(-$s/2,$s/2), $color);
    }
}   

$SESS = new session();
$SESS->setParameter('verifycode',$code);

for($i=0; $i<200*$r; $i++){
    $color = $im->setColor(mt_rand(0x0,0x66),mt_rand(0x0,0x66),mt_rand(0x0,0x66));
    $im->setPixel(mt_rand(0,$w), mt_rand(0,$h),$color);
}

$im->show();