PHP class generating CAPTCHA pictures

Published:

Add / read comments

Captcha is an acronym based on the word "capture" and standing for "Completely Automated Public Turing test to tell Computers and Humans Apart". Captcha is therefore very useful when we want to filter and collect only data inserted by humans only.

Mostly it is test, where human is asked to read and write down what is on the picture or there can be also some logical question.

So first we need some HTML. It's simple iframe tag which will be later reloading by simple JavaScript function. We also set optional attributes of an iframe.

<p>
  <iframe src="getCaptcha.php" id="captchaFrame" frameborder="0" height="40px" width="120px" 
          scrolling="no" marginheight="0px" marginwidth="0px">      
  </iframe>                                                 
  <img src="./reload.gif" alt="reload" title="new picture" onclick="reload();" />          
</p>

By clicking on the reload image, whole iframe is reloading by JavaScript function.

function reload() {

  // assign element into variable
  var f = document.getElementById('captchaFrame');
  
  // assign new element's source into old one
  f.src = f.src;
}

The CAPTCHA picture by itself is generated by PHP file "getCaptcha.php". Code inside of this file consist from only two lines of the code:

// link file with class
require('./captcha.class.inc.php');
 
// create instance of a class which generate CAPTCHA picture
$captcha = new CaptchaSafePic(120,40,6);

The heart of CAPTCHA system is PHP class, which is generating picture. Instance of a class is expecting three parameters: width of the picture, height of the picture and number of characters to be drawn. So let's have captcha class and we will set necessary data members:

class CaptchaSafePic {

  // private data members
  private $font = 'font.ttf';
  private $code = array();
 
  // rest of the class
}

For picture drawing we use type fonts specified in "ttf" file. On the web you may find many of free type fonts.

Class has only two method. First one is the constructor, who will make job almost done:

// object construction
public function __construct($width,$height,$characters) {
 
  // private method will generate code and store it in the variable
  $code = $this->generateCode($characters);		 
 
  // font size will be 60% 
  $font_size = $height * 0.6;
 
  // image creation
  $image = @imagecreate($width, $height) or die('Cold not create new image.');
 
  // set up background color
  $background_color = imagecolorallocate($image, 204, 255, 153); 
 
  // set up text color
  $text_color = imagecolorallocate($image, 0, 102, 0);
 
  // set up noise color
  $noise_color = imagecolorallocate($image, 51, 153, 51);
 
  // generate dash on the background
  for( $i=0; $i<($width*$height)/3; $i++ ) {

    imagefilledellipse($image, mt_rand(0,$width), mt_rand(0,$height), 1, 1, $noise_color);

  }
 
  // generate commas on the background
  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), $noise_color);

  }
 
  // create picture's borders and add text 
  $textbox = imagettfbbox($font_size, 0, $this->font, $code) 
               or die('Error in imagettfbbox function');

 
  // 0 = lower left x-coordinate  
  $x = array();
  $x[0] = ($textbox[0]+5); 	$x[1] = ($textbox[0]+20);
  $x[2] = ($textbox[0]+40); 	$x[3] = ($textbox[0]+60);
  $x[4] = ($textbox[0]+80); 	$x[5] = ($textbox[0]+95);
 
  // 1 = lower left y-coordinate
  $y = array();
  $y[0] = ($textbox[1]+30);   $y[1] = ($textbox[1]+20);
  $y[2] = ($height - $textbox[1]);   $y[3] = ($height/1.5 - $textbox[1]);
  $y[4] = ($height - $textbox[1]);   $y[5] = ($height/1.5 - $textbox[1]);
 
  // angle of text rotation
  $angle= array(10, 30, 0, 50, 20, 0);
 
  $k = 0;
  foreach($this -> code as $char){

    // write text into picture
    imagettftext($image, $font_size, $angle[$k], $x[$k], $y[$k], $text_color, $this->font , $char)
	or die('Error in imagettftext function');
    $k++;
  }
 
  // header set up
  header ("Content-type: image/png;");
 
  // image output
  imagepng($image);
 
  // destroy image
  imagedestroy($image);
 
  // insert the code into session
  $_SESSION['security_code'] = $code;
 
}

The second private method will generate the captcha code used in the picture.

private function generateCode($characters) {
 
  // list of letters from which code will be generated
  $possible = '123456789abcdefghjkmnpqrstvwxyz';
  $code = '';
  $i = 0;
 
  // cycle 
  while ($i < $characters) { 
    // randomly pick letter and assign it to private data array "code"
    $this->code[$i] = substr($possible,mt_rand(0,strlen($possible)-1), 1);
 
    // assign letter to variable "$code" 
    $code .= $this -> code[$i];
    $i++;
  }
  return $code;
}

So that's it! You can try live demo or download source code of the CAPTCHA PHP class, but please keep credits inside of the code intact.

Published:

Add / read comments

FIND ME

Share, follow or connect with me.