Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

imagemagick for captcha

i have a cronjob that generate captcha for my online forms (registration, contact and newsletter).

i generate over 5000 images per day so when i display the form, i randomly choose one and then simply display the image and set the session.

my table is very simple:

captcha (id mediumint(5) unsigned PK, phrase varchar(10));

and then i run the cronjob that generate images and insert into the DB. this process takes a while to run and I would like to know if there's a better way to do this, to maximize the performance and generation since i have other cronjob that runs all day and i want to make sure i can take this away from cronjob so my cronjob jobs can breath a little.

like image 493
Owan Avatar asked Feb 11 '12 02:02

Owan


1 Answers

Create a file call Captcha.class.php and put this:

class Captcha {
    private $font = '/path/to/font/yourfont.ttf'; // get any font you like and dont forget to update this.

    private function generateCode($characters) {
        $possible = '23456789bcdfghjkmnpqrstvwxyz'; // why not 1 and i, because they look similar and its hard to read sometimes
        $code = '';
        $i = 0;
        while ($i < $characters) {
            $code .= substr($possible, mt_rand(0, strlen($possible)-1), 1);
            $i++;
        }
        return $code;
    }

    function getImage($width, $height, $characters) {
        $code = $this->generateCode($characters);
        $fontSize = $height * 0.75;
        $image = imagecreate($width, $height);
        if(!$image) {
            return FALSE;
        }
        $background_color = imagecolorallocate($image, 255, 255, 255);
        $text_color = imagecolorallocate($image, 66, 42, 32);
        $noiseColor = imagecolorallocate($image, 150, 150, 150);
        for( $i=0; $i<($width*$height)/3; $i++ ) {
            imagefilledellipse($image, mt_rand(0,$width), mt_rand(0,$height), 1, 1, $noiseColor);
        }
        for( $i=0; $i<($width*$height)/150; $i++ ) {
            imageline($image, mt_rand(0,$width), mt_rand(0,$height), mt_rand(0,$width), mt_rand(0,$height), $noiseColor);
        }
        $textbox = imagettfbbox($fontSize, 0, $this->font, $code);
        if(!$textbox) {
            return FALSE;
        }
        $x = ($width - $textbox[4])/2;
        $y = ($height - $textbox[5])/2;
        imagettftext($image, $fontSize, 0, $x, $y, $text_color, $this->font , $code) or die('Error in imagettftext function');
        header('Content-Type: image/jpeg');
        imagejpeg($image);
        imagedestroy($image);
        $_SESSION['captcha'] = $code;
    }
}

Then in your page you can do:

<img src="/captcha.php" />

Then in the /captcha.php you will put:

session_start();
require('Captcha.class.php');
$Captcha = new Captcha();
$Captcha->getImage(120,40,6);

You can change the params as you wish to show different captcha too.

This way you will generate on the fly. You can always save the image on the disk if you want as well.

like image 197
Book Of Zeus Avatar answered Sep 22 '22 19:09

Book Of Zeus