How to Create a Captcha Image in PHP

0
722

captchaIMgFormatIn this tutorial, I will teach you how to create a captcha in PHP Captcha mostly seen if you are going to register or download in a website. This is a test for security purpose of a certain website to find out if the webuser is an adult or under age. Because there are some website that is for adults only and young web users are not allowed to access it.

 

Lets begin:

 

  • First, create a class for creating captcha image. Name it “loadcaptcha.php”.

[php]

session_start();
/** initialize */
$createcaptcha = new  CAPTCHA_LOADER();
/** load image */
$createcaptcha->Load_Image();

class CAPTCHA_LOADER {

/** set the width of the image */
public $img_width  = 250;

/** set the height of the image */
public $img_height = 50;

/** set the dictionary word file  */
public $words_File = ‘words/en.php’;

/**
* set a path for resource files (fonts, words, etc.)
*/
public $path = ‘captcha-resources’;

/** set the min word length  */
public $min_Word_Length = 4;

/**
* set the max word length
*/
public $max_Word_Length = 9;

/** set the session name to store the original text */
public $session_variable = ‘captcha’;

/** set the background color in RGB-array */
public $background_Color = array(255, 255, 255);

/** set foreground colors in RGB-array */
public $txtcolors = array(
array(27,78,181), // blue
array(22,163,35), // green
array(214,36,7),  // red
);

/** set the shadow color in RGB-array or null */
public $txtshadowColor = null; //array(0, 0, 0);

/** set the horizontal line through the text */
public $line_Width = 0;

/**
* set the font configuration
*/
public $fonts = array(
‘Antykwa’  => array(‘spacing’ => -3, ‘minSize’ => 27, ‘maxSize’ => 30, ‘font’ => ‘AntykwaBold.ttf’),
‘Candice’  => array(‘spacing’ =>-1.5,’minSize’ => 28, ‘maxSize’ => 31, ‘font’ => ‘Candice.ttf’),
‘Times’    => array(‘spacing’ => -2, ‘minSize’ => 28, ‘maxSize’ => 34, ‘font’ => ‘TimesNewRomanBold.ttf’),
‘VeraSans’ => array(‘spacing’ => -1, ‘minSize’ => 20, ‘maxSize’ => 28, ‘font’ => ‘VeraSansBold.ttf’),
‘Duality’  => array(‘spacing’ => -2, ‘minSize’ => 30, ‘maxSize’ => 38, ‘font’ => ‘Duality.ttf’),
‘Heineken’ => array(‘spacing’ => -2, ‘minSize’ => 24, ‘maxSize’ => 34, ‘font’ => ‘Heineken.ttf’),
‘Jura’     => array(‘spacing’ => -2, ‘minSize’ => 28, ‘maxSize’ => 32, ‘font’ => ‘Jura.ttf’),
‘StayPuft’ => array(‘spacing’ =>-1.5,’minSize’ => 28, ‘maxSize’ => 32, ‘font’ => ‘StayPuft.ttf’),
‘DingDong’ => array(‘spacing’ => -2, ‘minSize’ => 24, ‘maxSize’ => 30, ‘font’ => ‘Ding-DongDaddyO.ttf’),
);

/** set the wave configuracion in X and Y axes */
public $y_axis    = 10;
public $y_amplitude = 12;
public $x_axis    = 9;
public $x_amplitude = 3;

/** letter rotation clockwise */
public $max_rotation = 10;

/**
* set the internal image size factor
*/
public $img_scale =1 ;

/**
* set the blur effect for better image quality (slower image process).
*/
public $img_blur = false;

/** Debug image? */
public $img_debug = false;

/** set image format: jpeg or png */
public $imgFormat = ‘jpeg’;

/** set  GD image */
public $gd_Image;

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

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

/** Initialization */
$this->Image_Allocate();

/** Text insertion */
$text = $this->GetCaptchaText();
$fontcfg  = $this->fonts[array_rand($this->fonts)];
$this->Write_Text($text, $fontcfg);

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

/** Transformations */
if (!empty($this->line_Width)) {
$this->Write_Line();
}
$this->Wave_Image();
if ($this->img_blur && function_exists(‘imagefilter’)) {
imagefilter($this->gd_Image, IMG_FILTER_GAUSSIAN_BLUR);
}
$this->Reduce_Image();

if ($this->img_debug) {
imagestring($this->gd_Image, 1, 1, $this->img_height-8,
“$text {$fontcfg[‘font’]} “.round((microtime(true)-$ini)*1000).”ms”,
$this->GdFgColor
);
}

/** Output */
$this->Write_Image();
$this->CleaningUp();
}

/**
* Creates the image resources
*/
protected function Image_Allocate() {
// Cleaning Up
if (!empty($this->gd_Image)) {
imagedestroy($this->gd_Image);
}

$this->gd_Image = imagecreatetruecolor($this->img_width*$this->img_scale, $this->img_height*$this->img_scale);

// Background color
$this->GdBgColor = imagecolorallocate($this->gd_Image,
$this->background_Color[0],
$this->background_Color[1],
$this->background_Color[2]
);
imagefilledrectangle($this->gd_Image, 0, 0, $this->img_width*$this->img_scale, $this->img_height*$this->img_scale, $this->GdBgColor);

// Foreground color
$color           = $this->txtcolors[mt_rand(0, sizeof($this->txtcolors)-1)];
$this->GdFgColor = imagecolorallocate($this->gd_Image, $color[0], $color[1], $color[2]);

// Shadow color
if (!empty($this->txtshadowColor) && is_array($this->txtshadowColor) && sizeof($this->txtshadowColor) >= 3) {
$this->GdShadowColor = imagecolorallocate($this->gd_Image,
$this->txtshadowColor[0],
$this->txtshadowColor[1],
$this->txtshadowColor[2]
);
}
}

/**
* create a text generation
*/
protected function GetCaptchaText() {
$text = $this->GetCaptchaTextDictionary();
if (!$text) {
$text = $this->GetRandomCaptchaText();
}
return $text;
}

/**
* set a random text generation
*/
protected function GetRandomCaptchaText($length = null) {
if (empty($length)) {
$length = rand($this->min_Word_Length, $this->max_Word_Length);
}

$words  = “abcdefghijlmnopqrstvwyz”;
$vocals = “aeiou”;

$text  = “”;
$vocal = rand(0, 1);
for ($i=0; $i<$length; $i++) {
if ($vocal) {
$text .= substr($vocals, mt_rand(0, 4), 1);
} else {
$text .= substr($words, mt_rand(0, 22), 1);
}
$vocal = !$vocal;
}
return $text;
}

/**
* set a random dictionary word generation
*/
function GetCaptchaTextDictionary($extended = false) {
if (empty($this->words_File)) {
return false;
}

// Full path of words file
if (substr($this->words_File, 0, 1) == ‘/’) {
$words_file = $this->words_File;
} else {
$words_file = $this->path.’/’.$this->words_File;
}

if (!file_exists($words_file)) {
return false;
}

$fp     = fopen($words_file, “r”);
$length = strlen(fgets($fp));
if (!$length) {
return false;
}
$line   = rand(1, (filesize($words_file)/$length)-2);
if (fseek($fp, $length*$line) == -1) {
return false;
}
$text = trim(fgets($fp));
fclose($fp);

/** Change ramdom volcals */
if ($extended) {
$text   = preg_split(‘//’, $text, -1, PREG_SPLIT_NO_EMPTY);
$vocals = array(‘a’, ‘e’, ‘i’, ‘o’, ‘u’);
foreach ($text as $i => $char) {
if (mt_rand(0, 1) && in_array($char, $vocals)) {
$text[$i] = $vocals[mt_rand(0, 4)];
}
}
$text = implode(”, $text);
}

return $text;
}

/**
* create a horizontal line insertion
*/
protected function Write_Line() {

$x1 = $this->img_width*$this->img_scale*.15;
$x2 = $this->textFinalX;
$y1 = rand($this->img_height*$this->img_scale*.40, $this->img_height*$this->img_scale*.65);
$y2 = rand($this->img_height*$this->img_scale*.40, $this->img_height*$this->img_scale*.65);
$img_width = $this->line_Width/2*$this->img_scale;

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

/**
* create a text insertion
*/
protected function Write_Text($text, $fontcfg = array()) {
if (empty($fontcfg)) {
// Select the font configuration
$fontcfg  = $this->fonts[array_rand($this->fonts)];
}

// Full path of font file
$fontfile = $this->path.’/fonts/’.$fontcfg[‘font’];

/** Increase font-size for shortest words: 9% for each glyp missing */
$lettersMissing = $this->max_Word_Length-strlen($text);
$fontSizefactor = 1+($lettersMissing*0.09);

// Text generation (char by char)
$x      = 20*$this->img_scale;
$y      = round(($this->img_height*27/40)*$this->img_scale);
$length = strlen($text);
for ($i=0; $i<$length; $i++) {
$degree   = rand($this->max_rotation*-1, $this->max_rotation);
$fontsize = rand($fontcfg[‘minSize’], $fontcfg[‘maxSize’])*$this->img_scale*$fontSizefactor;
$letter   = substr($text, $i, 1);

if ($this->txtshadowColor) {
$coords = imagettftext($this->gd_Image, $fontsize, $degree,
$x+$this->img_scale, $y+$this->img_scale,
$this->GdShadowColor, $fontfile, $letter);
}
$coords = imagettftext($this->gd_Image, $fontsize, $degree,
$x, $y,
$this->GdFgColor, $fontfile, $letter);
$x += ($coords[2]-$x) + ($fontcfg[‘spacing’]*$this->img_scale);
}

$this->textFinalX = $x;
}

/**
* create a wave filter
*/
protected function Wave_Image() {
// X-axis wave generation
$xp = $this->img_scale*$this->x_axis*rand(1,3);
$k = rand(0, 100);
for ($i = 0; $i < ($this->img_width*$this->img_scale); $i++) {
imagecopy($this->gd_Image, $this->gd_Image,
$i-1, sin($k+$i/$xp) * ($this->img_scale*$this->x_amplitude),
$i, 0, 1, $this->img_height*$this->img_scale);
}

// Y-axis wave generation
$k = rand(0, 100);
$yp = $this->img_scale*$this->y_axis*rand(1,2);
for ($i = 0; $i < ($this->img_height*$this->img_scale); $i++) {
imagecopy($this->gd_Image, $this->gd_Image,
sin($k+$i/$yp) * ($this->img_scale*$this->y_amplitude), $i-1,
0, $i, $this->img_width*$this->img_scale, 1);
}
}

/**
* set and reduce the image to the final size
*/
protected function Reduce_Image() {
// Reduzco el tamaño de la imagen
$imResampled = imagecreatetruecolor($this->img_width, $this->img_height);
imagecopyresampled($imResampled, $this->gd_Image,
0, 0, 0, 0,
$this->img_width, $this->img_height,
$this->img_width*$this->img_scale, $this->img_height*$this->img_scale
);
imagedestroy($this->gd_Image);
$this->gd_Image = $imResampled;
}

/**
* create a file generation
*/
protected function Write_Image() {
if ($this->imgFormat == ‘png’ && function_exists(‘imagepng’)) {
header(“Content-type: image/png”);
imagepng($this->gd_Image);
} else {
header(“Content-type: image/jpeg”);
imagejpeg($this->gd_Image, null, 80);
}
}

/**
* create the cleaning up method
*/
protected function CleaningUp() {
imagedestroy($this->gd_Image);
}
}

[/php]

  • Second, do this following code for viewing the captcha. Name it “index.php”.

[html]

<h3>Test if you are human.</h3>
<div onload=”document.getElementById(‘strcaptcha’).focus()”>
<form action=”” method=”post”>
<img id=”imgcaptcha” src=”loadcaptcha.php”><br>
<!– Changing captcha –>
<a href=”#” onclick=”LoadCaptcha()”>Reload Captcha.</a><br>
<br>
<!– end changing –>
<input autocomplete=”off” id=”strcaptcha” name=”strcaptcha” type=
“text”><br>
<input name=”submit” type=”submit”>
</form>

[/html]

  • Third, create a script for refreshing the captcha.

[javascript]

/* create a function for changing capcha */
function LoadCaptcha() {
document.getElementById(‘imgcaptcha’).src = ‘loadcaptcha.php?’ + Math.random();
document.getElementById(‘strcaptcha’).focus();
}

[/javascript]

  • Finally, create a method for validating the captcha.

[php]

/* start the session*/
session_start();
/** Validating captcha */
if (isset($_POST[‘strcaptcha’])) {
if (empty($_SESSION[‘captcha’]) || trim(strtolower($_POST[‘strcaptcha’])) != $_SESSION[‘captcha’]) {
$msg = “Invalid captcha”;
$color = “background-color: #FF606C”;
} else {
$msg = “Valid captcha”;
$color = “background-color: #CCFF99”;
}
/* requesting captcha */
htmlspecialchars($_POST[‘strcaptcha’]);
/* load message */
echo $view = “<div id=’result’ style='”.$color.”‘ >
<p><h2>”.$msg.”</h2></p>
</div>”;
/* clearing captcha */
unset($_SESSION[‘captcha’]);
}

[/php]

 

For all students who need programmer for your thesis system or anyone who needs a sourcecode in any programming languages.  You can contact me @ :

 

Email – [email protected]

Mobile No. – 09305235027 – tnt

Download Sourcecode

Looking for more source code? Type your keyword here here!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.