Home arrow Articles arrow Image Verification Class
Image Verification Class PDF Print E-mail
Written by Administrator   
Saturday, 27 October 2007
I set out to create some image verification code to add to my scripts to verify human users. The best way to do this in a way that i can reuse it is in a class. Here is the first working version of this class.

N.B. You Need PHP5 to make use of this class.

 
PHP Code:
 
class iv
{
    
   
/****************************************************************************************     
   Random key generator     
   ****************************************************************************************/
    //Temp array for storing key
    
private $_storky = array();
    
//variable for storing timestamp
    
private $_stamp
    
//variable for storing key when generated by internal keygen
    
private $outkey;
    
//variable maximum number of characters in generated key
    
private $char_limit 10;    
    
//Public function to set the number of desired characters in key
    
public function setCharLimit($new_limit){
        
$this->char_limit $new_limit;
        }
    
//public function to get the number of desired characters in key    
    
public function getCharLimit(){
        return 
$this->char_limit;
        }
    
//public function to generate random key        
    
public function definekey() {    
        
$_number = array(48,57);
        
$_letter = array(97,122);
        
$_anames = array("_number","_letter"); 
        
            for(
$i=0;$i<$this->char_limit;$i++){
                
//first character is a letter
                
if($i==0){$_setchr=1;}
                else { 
$_setchr rand(0,1);}
                
//select a number or letter
                
$selected_array = $$_anames[$_setchr];
                
//insert selected character
                
$this->_storky[$i] = chr(rand($selected_array[0],$selected_array[1]));
                }            
            
//store generated key
             
$this->setkey(implode($this->_storky));
            }
//public function to create a key with only numbers. SetCharlimit doesnt apply        
    
public function defineNumOnlyKey(){
        
$this->_stamp  =  time();        
        
$_myrand rand(10000,$this->_stamp);    
        
$_ar_rand str_split($_myrand);        
        
$_ranend array_rand($_ar_rand,4);    
        
$r_start $_ranend[0].$_ranend[1].$_ranend[2].$_ranend[3];        
        
$r_stamp substr(str_shuffle($this->_stamp),0,6);        
        
$_stamod str_shuffle($r_start).$r_stamp;            
        
$this->setkey($_stamod rand(10,20));
        }
    
//public function to store key. Can be used to store externally generated key.    
    
public function setkey($newkey){
        
$this->use_default_keygen false;
        
$this->outkey $newkey;        
        }
    
//public function to return stored key    
    
public function getkey(){
        return 
$this->outkey;
        }
   
/****************************************************************************************     
   Portion having to do with image creation     
   *****************************************************************************************/
     //image dimensions
    
private $img_height;
    
private $img_width;

             
//percentage by which to increase image size. Used with function magnify()    
    
private $ratio 0;
            
//the filename of the outputed image
    
private $img_file_name ;
            
//the image font color array
    
private $font_color = array(3);
            
//the image background color array
    
private $bg_color = array(3);
            
//the image line color array
    
private $line_color = array(3);

            
/*******************************
 the Following boolean values are switches to force default behaviour of certain values are not set by corresponding methods. E.G. If $this->definey() is not called and $this->setkey() is not called $this->definekey() will be called by default
           ***************************************/
    
private $use_default_bg true;
    
private $use_default_fc true;
    
private $use_default_dim true;
    
private $use_default_img_n true;
    
private $use_default_keygen true;
    
private $use_default_lc true;
             
//private function which sets default values if public functions to set values externally are not called
    
private function setworkingvalues(){
            if(
$this->use_default_img_n){$this->img_file_name "iv_img_file.png";}
            if(
$this->use_default_keygen){$this->definekey();}
            if(
$this->use_default_dim){$this->setDimensions(70,25);}
            if(
$this->use_default_bg){$this->setbgcolor(222,223,224) ;}
            if(
$this->use_default_fc){$this->setfontcolor(233,14,91) ;}
            if(
$this->use_default_lc){$this->setlinecolor(156,159,163);}
            }    
                
       
public function setDimensions($width,$height){
        
$this->use_default_dim false;
           
$this->img_height $height;
           
$this->img_width $width;
           }
        
    
public function setbgcolor($r,$g,$b){
        
$this->use_default_bg false;
        
$this->bg_color[0] = $r;
        
$this->bg_color[1] = $g;
        
$this->bg_color[2] = $b;
        }
    
public function setfontcolor($r,$g,$b){
        
$this->use_default_fc false;
        
$this->font_color[0] = $r;
        
$this->font_color[1] = $g;
        
$this->font_color[2] = $b;
        }
    
public function setlinecolor($r,$g,$b){
        
$this->use_default_lc false;
        
$this->line_color[0] = $r;
        
$this->line_color[1] = $g;
        
$this->line_color[2] = $b;
        }
    
public function magnify($newratio){
        
$this->ratio $newratio;
        }
           
    
public function getWidth(){
            return 
$this->img_width;
           }           
    
public function getHeight(){
        return 
$this->img_height;
        }
        
    
public function initIV(){
         
header ("Content-type: image/png");
        
        
$this->setworkingvalues();
        
        
$im = @imagecreatetruecolor($this->img_width,$this->img_height)
      or die(
"Error. Ensure Gd2 is available in phpInfo");
        
$text_color imagecolorallocate($im$this->font_color[0], $this->font_color[1], $this->font_color[2]);
        
$back_color imagecolorallocate($im$this->bg_color[0],$this->bg_color[1], $this->bg_color[2]);
        
$stroke_color imagecolorallocate($im$this->line_color[0], $this->line_color[1],$this->line_color[2]);
        
ImageFill($im,0,0,$back_color);
        
imageline($im,0,0,100,25,$stroke_color);
        
ImageString($im5155,$this->getkey(), $text_color);
        
/************************
                         if no magnification ratio set 
                         the image will be displayed at $this->img_height and $this->img_width
                         ************************************/
        
if($this->ratio!=&& is_int($this->ratio)){
            
$h $this->img_height * (($this->ratio/100) + 1);
            
$w =  $this->img_width * (($this->ratio/100) + 1);
            
$zoom_height is_float($h)?round($h):$h;
            
$zoom_width is_float($w)?round($w):$w;
            
$zoom = @imagecreatetruecolor($zoom_width,$zoom_height);
            
imagecopyresized($zoom$im0000$zoom_width$zoom_height$this->img_width$this->img_height);
            
imagepng($zoom,$this->img_file_name);
            
imagedestroy($zoom);
            
imagedestroy($im);
            }

        else {
            
imagepng($im,$this->img_file_name);
            
imagedestroy($im);
            }
        }
    
    
public function getImageName(){
        return 
$this->img_file_name;
        }    
    
public function setImageName($new_img_name){
        
$this->use_default_img_n false;
        
$this->$img_file_name $new_img_name;
        }
    }
    
             
?> 


Sample implementation

Create a php file eg. index.php and add the following code

PHP Code:
 
<?php 
 session_start
();
 include(
'iv_class.php');
 
$mykey = new iv();
 
$mykey->setCharLimit(5);
//if the line below is uncommented the output image should grow in size
//the value 50 is a ratio meaning 50%
 //$mykey->magnify(50);
 
$mykey->initIV();
 
$_SESSION['humankey'] = $mykey->getkey();
echo 
"<img src='".$mykey->getImageName()".'>";
echo 
"<form action='iv_verify.php' method=post>";
echo 
"<input type='text' name='human'>";
echo 
"<input type='submit'>";
 
?>

Here is a preview of this file when opened in the browser.


I know what you are thinking....all that for that???
That is what a class does. It allows different people to use it for different situations. Naturally if this were a simple image verification there wouldn't be as much code. enjoy!!

PHP verification File

place the following code into a file iv_verify.php

Note well the following code is not meant to be just pasted in your production script. It is merely an example of the use of the class.
PHP Code:
 
<?php
session_start
();
echo 
"Challenge Code:   ".$_POST['human']."<br>";
echo 
"Your Entery:   ".$_SESSION['humankey']."<br>";

if(
$_POST['human'] == $_SESSION['humankey']){
echo 
"you have been verified!!";
}
else {echo 
"wrong code entered!!";}
?>

To-Do List

[1] Dynamic image format output
I am certain that the default png format will not be the desired output for all persons wishing to use this class. I will be adding a few public methods. Called SetImageTypeExt(), GetImageTypeExt(), GetImageTypeMime().

This addition will be useful for persons wanting to use this class for a wap application. it would be something like this.

PHP Code:
 
/**
the following directive sets the output image 
to the wbmp format commonly used on mobile phone browsers.
**/
$myiv->SetImageTypeExt('wbmp'); 

[2]adding output buffering as an element of the class. As it is, the iv class basically generates an image file which is then outputed via the header() directive which cannot be sent to the browser at any point. Else you will get an error. http://www.php.net/header I am doing some testing to determine the correct way to implement this.

here is the idea......
PHP Code:
 
<?php
$myiv 
= new iv();
//Run all iv methods to get and set desired values
$myiv->holdOutput();
?>
<html>
hello world. Please enter something in my form before you you go any further
<?php
$myiv
->initIV();
$myiv->OutputForm();
$myiv->ReleaseOutput();
?>
</html>

[3] Public function to output a pre-designed verification form. Here is the idea. Someone making use of this class can have the option of using a public function to output a form.

so instead of the following..

PHP Code:
 
session_start();
 include(
'iv_class.php');
 
$mykey = new iv();
 
$mykey->setCharLimit(5);
 
//$mykey->magnify(50);
 
$mykey->initIV();
 
$_SESSION['humankey'] = $mykey->getkey();
echo 
"<img src='iv_img_file.png'>";
echo 
"<form action='iv_verify.php' method=post>";
echo 
"<input type='text' name='human'>";
echo 
"<input type='submit'>";
 
?> 

you can optionally do this.

PHP Code:
 
session_start();
 include(
'iv_class.php');
 
$mykey = new iv();
 
$mykey->setCharLimit(5);
 
//$mykey->magnify(50);
 
$mykey->initIV();
 
$_SESSION['humankey'] = $mykey->getkey();
 
$mykey->OutputForm();
 
?> 

Further to this a second method setFormHtml() Can be added. As with all other public set methods if it is not called a default will be assumed!
PHP Code:
 
//somewher in site definitions
 
$key_form_html "<form action=iv_verify.php>"//full custom form code
 
?> 
verification page now sets this info to the class to be outputed
PHP Code:
 
session_start();
 include(
'iv_class.php');
 
$mykey = new iv();
 
$mykey->setCharLimit(5);
 
//$mykey->magnify(50);
 
$mykey->initIV();
 
$_SESSION['humankey'] = $mykey->getkey();
 
$mykey->SetFormHTML($key_form_html);
 
$mykey->OutputForm();
 
?> 
or
PHP Code:
 
$mykey->SetFormHTML('templates/currentTemplate/verify.html');
$mykey->OutputForm(); 

[4] Verify values supplied to set colors are valid rgb entries
exampe..
PHP Code:
 
public setfontcolor($r,$g,$b){
    if(
validColor($r,$g,$b){
            
$this->use_default_fc false;
            
$this->font_color[0]=$r;
            
$this->font_color[1]=$g;
            
$this->font_color[2]=$b;
            }
      
        } 
i am not sure how to warn a programmer that his supplied color is not valid...except for them to see that the colour doesnt change??

[5] Random background colors An option of having random background colors for the image can be added by simply adding colours to be used in this functionality.

PHP Code:
 
$myiv = new iv();
//add one color
$myiv->AddRandBG($r,$g,$b);
//add second color
$myiv->AddRandBG($r1,$g1,$b1);
//add third color
$myiv->AddRandBG($r2,$g2,$b2); 

Upon image creation the image background color will be randomly selected from those supplied.

[6] Load font files

currently the library has 4 fonts to choose from..One would optionally be able to add their own fonts

PHP Code:
 
$myiv = new iv();
$myiv->UseFontFile($pathToFont); 

[7] Load Background image

This is a public method that allows a custom background to be loaded in. Using this method will automatically overide the setbgcolor() method.
PHP Code:
 
$myiv = new iv();
$mybgfile "bgfile.png";
$myiv->LoadBgFile($mybgfile); 




Add to favourite articles (28) | Place this article on your website | Views: 275

Comment on this article
RSS comments

Only registered users can write comments.
Please login or register.

blabh
Last Updated ( Sunday, 02 December 2007 )