By Rodney Amato
More PHP Code
We will start with a basic script that reads the text from the session and creates an image from it:
/**
* CreateCaptchaImage
*
* Create the captcha image based on the secret in the captcha variables
*
* @return false If we are unable to generate an image return false
*/
function CreateCaptchaImage()
{
// Why generate images if we can't ?
if (!function_exists('imageCreateFromPNG')) {
return false;
}
if (!function_exists('imagettftext')) {
return false;
}
if (empty($_SESSION['captcha'])) {
return false;
}
if (!is_file(dirname(__FILE__).'/captcha.ttf') {
return false;
}
$width = 150;
$height = 50;
$fontSize = 24;
$x = 30;
$y = 35;
$angle = 0;
header('Content-type: image/png');
$img_handle = imageCreate($width, $height);
// The first colour allocated to the pallet is our background
ImageColorAllocate ($img_handle, 255, 150, 150);
// Set our text to black
$text_color = ImageColorAllocate ($img_handle, 0, 0, 0);
imagettftext($img_handle, $fontSize, $angle, $x, $y, $text_color, dirname(__FILE__).'/captcha.ttf', $_SESSION['captcha']);
// Increment the number of times we have looked at the captcha in the session
$_SESSION['captchaLoads']++;
ImagePng ($img_handle);
ImageDestroy ($img_handle);
}
CreateCaptchaImage(); The script that generates our image will need to do some things to try and make it harder for a computer program to read the image.
Alter the background
Change the position of the text
Alter the font
Alter the background
We can do this two ways. First, we can do this:
Change
// The first colour allocated to the pallet is our backgroundto something like
... which will change the background randomly (we use 100 as the starting value so that, assuming we keep the text black, the text will still be visible to the user fairly easily). We could also use the various GD image fill functions to give us various gradient fills for the background.
Alternatively we can change the line:
The PickRandomBackgroundFile function would be something like this:
/**
* PickRandomBackgroundFile
*
* Choose a random .png file from the backgrounds directory
*
* @return mixed False on any problem, the full path to the background file if
* a file in the right directory with a png extension was found
*/
function PickRandomBackgroundFile()
{
$dir = dirname(__FILE__).'/backgrounds';
$files = array();
if (!is_dir($dir)) {
return false;
}
$dh = opendir($dir);
if ($dh === false) {
return false;
}
while (($file = readdir($dh)) !== false) {
// Skip checking the current and parent directory
if ($file == '.' || $file == '..') {
continue;
}
if (is_file($dir.'/'.$file)) {
$parts = explode('.', $file);
$ext = array_pop($parts);
if (strtolower($ext) == 'png') {
$files[] = $dir.'/'.$file;
}
}
}
if (empty($files)) {
return false;
}
return $files[array_rand($files)];
} Change the Position of the Text
The imagettftext function can take an angle at which it will draw the text on an image. So we can change this line:
...to this:
... and the text will move around a bit (+/- 5 degrees). We should also change the $x and $y a bit too but I'll leave that up to you.
Altering the Font
Another thing that we can do is choose the font at random from a selection of fonts. We can alter our previous PickRandomBackgroundFile function to be more generic so it looks like this:
/**
* PickRandomFile
*
* Choose a random file from the given directory
*
* @param string $dir The directory to look in
* @param string $extension The lowercase version of the extension to look for
* @return mixed False on any problem, the full path to the background file if
* a file in the right directory with a png extension was found
*/
function PickRandomFile($dir, $extension)
{
$files = array();
if (!is_dir($dir)) {
return false;
}
if (empty($extension)) {
return false;
}
$dh = opendir($dir);
if ($dh === false) {
return false;
}
while (($file = readdir($dh)) !== false) {
// Skip checking the current and parent directory
if ($file == '.' || $file == '..') {
continue;
}
if (is_file($dir.'/'.$file)) {
$parts = explode('.', $file);
$ext = array_pop($parts);
if (strtolower($ext) == $extension) {
$files[] = $dir.'/'.$file;
}
}
}
if (empty($files)) {
return false;
}
return $files[array_rand($files)];
} We can call the PickRandomFile function like this:
$fontFile = PickRandomFile(dirname(__FILE__).'/fonts', 'ttf') ...and it will pick a random font for us. We can also use this for our backgrounds like so:
$backgroundFile = PickRandomFile(dirname(__FILE__).'/fonts', 'png');