Show Me the PHP!
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 background ImageColorAllocate ($img_handle, 255, 150, 150); to something like // The first colour allocated to the pallet is our background ImageColorAllocate ($img_handle, rand(100, 255), rand(100, 255), rand(100, 255)); ... 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: $img_handle = imageCreate($width, $height); which creates a blank image, to something like this:
$file = PickRandomBackgroundFile(); $img_handle = imagecreatefrompng($file); 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:
$angle = 0; ...to this:
$angle = rand(-5, 5); ... 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');
|