Captcha from scratch (PHP / GD)
2010-08-11 07:51 by Ian
/**************************************************************************
* Author: J. Ian Lindsay *
* File: captcha.php *
* *
* Generates a captcha and updates the session. Ensures that the captcha *
* is readable and recurses if it isn't. *
**************************************************************************/
require_once("include/session.php");
define('RENDER_WIDTH', 350); // How big an image to generate?
define('RENDER_HEIGHT', 80);
define('TEXTURE_PATH', "include/escher_grid_ps.jpg"); // File to draw background noise from.
define('ANGLE_DEV', 25); // Maximum deviation from horizontal, in degrees.
define('FONT_PATH', "include/courbd.ttf"); // Font to write the captcha text with.
define('TEXT_SIZE', 20); // Pixel height of the text.
define('DICT_PATH', "include/8-letter-words.txt"); // Path to the dictionary.
define('C_RANGE_LOW', 0); // The darkest any random color channel can be.
define('C_RANGE_HIGH', 190); // The brightest any random color channel can be.
// Return a random word from a comma-delimited dictionary file located at DICT_PATH.
function randomWordFromDict(){
$read = file_get_contents(DICT_PATH);
$words = explode(",", $read);
return($words[rand(0,count($words)-1)]);
}
// Copy a region of the desired size from the source texture file at random. This will prevent
// bots from subtracting a known-texture to remove visual noise.
// If a texture file is specified that is too small, it will not use a texture, but will return
// an image anyway.
function cropFromTextureFile(){
$img = imagecreatefromjpeg(TEXTURE_PATH);
$area = imagecreatetruecolor(RENDER_WIDTH, RENDER_HEIGHT);
imagefill($img,0,0,imagecolorallocatealpha($img, 255,255,255,0));
$tex_width = imagesx($img);
$tex_height = imagesy($img);
if(($tex_width > RENDER_WIDTH) && ($tex_height > RENDER_HEIGHT)){
imagecopy($area, $img, 0, 0, rand(0,$tex_width-RENDER_WIDTH), rand(0,$tex_height-RENDER_HEIGHT), RENDER_WIDTH, RENDER_HEIGHT);
}
imagerectangle($area, 0, 0, RENDER_WIDTH - 1, RENDER_HEIGHT - 1, imagecolorallocate($area, 0, 0, 0));
return($area);
}
// Generates a captcha and updates a session variable accordingly.
function generateCaptcha(){
$img = cropFromTextureFile();
$image_text = randomWordFromDict();
$text_color = imagecolorallocate($img,rand(C_RANGE_LOW,C_RANGE_HIGH),rand(C_RANGE_LOW,C_RANGE_HIGH),rand(C_RANGE_LOW,C_RANGE_HIGH));
$output = imagettftext($img, TEXT_SIZE, (rand((0-ANGLE_DEV),ANGLE_DEV)), rand(0,RENDER_WIDTH-(TEXT_SIZE*strlen($image_text))), rand(TEXT_SIZE,RENDER_HEIGHT-TEXT_SIZE), $text_color,FONT_PATH, $image_text);
$_SESSION['captcha'] = $image_text; // Must happen before recursion.
if(($output[2] > RENDER_WIDTH) || ($output[4] > RENDER_WIDTH) || (($output[3]+(TEXT_SIZE/2)) > RENDER_HEIGHT) || ($output[5] < (TEXT_SIZE/2))){
$img = generateCaptcha();
}
return($img);
}
header("Content-type:image/jpeg");
header("Content-Disposition:inline ; filename=secure.jpg");
imagejpeg(generateCaptcha());
Click the image for a different word.
Previous: Nitrogen Triiodide
Next: Lojban parser