Просмотр файла engine/classes/captcha.php

Размер файла: 6.32Kb
<?php

class SimpleCaptcha {

    
    public $width  = 150;
    public $height = 60;
    public $minWordLength = 3;
    public $maxWordLength = 6;
    public $session_var = 'captcha';
    public $backgroundColor = array(255, 255, 255);
    public $colors = array(
        array(27,78,181),         array(22,163,35),         array(214,36,7),      );

    public $shadowColor = null; 
    public $lineWidth = 0;
    public $Yperiod    = 12;
    public $Yamplitude = 14;
    public $Xperiod    = 11;
    public $Xamplitude = 5;
    public $maxRotation = 7;
    public $scale = 2;
    public $blur = false;
    public $debug = false;
    public $im;
	public $font_config = array('spacing' => 1, 'minSize' => 17, 'maxSize' => 19);

    public function __construct($config = array()) {
    }

    public function CreateImage() {
        $ini = microtime(true);

        
        $this->ImageAllocate();
        
        
        $text = $this->GetRandomCaptchaText();
        $this->WriteText($text);

        $_SESSION[$this->session_var] = $text;

        
        if (!empty($this->lineWidth)) {
            $this->WriteLine();
        }
        $this->WaveImage();
        if ($this->blur && function_exists('imagefilter')) {
            imagefilter($this->im, IMG_FILTER_GAUSSIAN_BLUR);
        }
        $this->ReduceImage();


        if ($this->debug) {
            imagestring($this->im, 1, 1, $this->height-8,
                "$text ".round((microtime(true)-$ini), 4)."ms",
                $this->GdFgColor
            );
        }


        
        $this->WriteImage();
    }


    
    protected function ImageAllocate() {
                if (!empty($this->im)) {
            imagedestroy($this->im);
        }

        $this->im = imagecreatetruecolor($this->width*$this->scale, $this->height*$this->scale);

                $this->GdBgColor = imagecolorallocate($this->im,
            $this->backgroundColor[0],
            $this->backgroundColor[1],
            $this->backgroundColor[2]
        );
		//imagecolortransparent($this->im, $this->GdBgColor);
        imagefilledrectangle($this->im, 0, 0, $this->width*$this->scale, $this->height*$this->scale, $this->GdBgColor);

                $color           = $this->colors[mt_rand(0, sizeof($this->colors)-1)];
        $this->GdFgColor = imagecolorallocate($this->im, $color[0], $color[1], $color[2]);

                if (!empty($this->shadowColor) && is_array($this->shadowColor) && sizeof($this->shadowColor) >= 3) {
            $this->GdShadowColor = imagecolorallocate($this->im,
                $this->shadowColor[0],
                $this->shadowColor[1],
                $this->shadowColor[2]
            );
        }
    }

    
    protected function GetRandomCaptchaText($length = null) {
        if (empty($length)) {
            $length = rand($this->minWordLength, $this->maxWordLength);
        }

        $words  = 'bcdfghjlmnpqrstvwyz';
        $vocals = 'aeoui';

        $text  = null;
        $vocal = rand(0, 1);
        while (strlen($text) < $length)
		{
            if ($vocal) {
                $text .= substr($vocals, mt_rand(0, 4), 1); //$vocals{mt_rand(0, 4)}; //
				$vocal = false;
            } else {
                $text .= substr($words, mt_rand(0, 22), 1); //$words{mt_rand(0, 22)};
				$vocal = true;
            }
        }
        return $text;
    }


    
    protected function WriteLine() {

        $x1 = $this->width*$this->scale*.15;
        $x2 = $this->textFinalX;
        $y1 = rand($this->height*$this->scale*.40, $this->height*$this->scale*.65);
        $y2 = rand($this->height*$this->scale*.40, $this->height*$this->scale*.65);
        $width = $this->lineWidth/2*$this->scale;

        for ($i = $width*-1; $i <= $width; $i++) {
            imageline($this->im, $x1, $y1+$i, $x2, $y2+$i, $this->GdFgColor);
        }
    }




    
    protected function WriteText($text) {

        $fontfile = $_SERVER['DOCUMENT_ROOT'] . '/engine/files/data/font.ttf';
        $lettersMissing = $this->maxWordLength-strlen($text);
        $fontSizefactor = 1+($lettersMissing*0.09);

                $x      = 20*$this->scale;
        $y      = round(($this->height*27/40)*$this->scale);
        $length = strlen($text);
        for ($i=0; $i<$length; $i++) {
            $degree   = rand($this->maxRotation*-1, $this->maxRotation);
            $fontsize = rand($this->font_config['minSize'], $this->font_config['maxSize'])*$this->scale*$fontSizefactor;
            $letter   = substr($text, $i, 1);

            if ($this->shadowColor) {
                $coords = imagettftext($this->im, $fontsize, $degree,
                    $x+$this->scale, $y+$this->scale,
                    $this->GdShadowColor, $fontfile, $letter);
            }
            $coords = imagettftext($this->im, $fontsize, $degree,
                $x, $y,
                $this->GdFgColor, $fontfile, $letter);
            $x += ($coords[2]-$x) + ($this->font_config['spacing'] * $this->scale);
        }

        $this->textFinalX = $x;
    }

    
    protected function WaveImage() {
                $xp = $this->scale*$this->Xperiod*rand(1,3);
        $k = rand(0, 100);
        for ($i = 0; $i < ($this->width*$this->scale); $i++) {
            imagecopy($this->im, $this->im,
                $i-1, sin($k+$i/$xp) * ($this->scale*$this->Xamplitude),
                $i, 0, 1, $this->height*$this->scale);
        }

                $k = rand(0, 100);
        $yp = $this->scale*$this->Yperiod*rand(1,2);
        for ($i = 0; $i < ($this->height*$this->scale); $i++) {
            imagecopy($this->im, $this->im,
                sin($k+$i/$yp) * ($this->scale*$this->Yamplitude), $i-1,
                0, $i, $this->width*$this->scale, 1);
        }
    }

    protected function ReduceImage() {
                $imResampled = imagecreatetruecolor($this->width, $this->height);
        imagecopyresampled($imResampled, $this->im,
            0, 0, 0, 0,
            $this->width, $this->height,
            $this->width*$this->scale, $this->height*$this->scale
        );
        imagedestroy($this->im);
        $this->im = $imResampled;
    }


    protected function WriteImage() {
        header("Content-type: image/png");
        imagepng($this->im);
		imagedestroy($this->im);
    }
}