And the code from Sources/Subs-Graphics.
// Create the image for the visual verification code.
function showCodeImage($code)
{
global $settings;
// Is this GD2? Needed for pixel size.
$testGD = get_extension_funcs('gd');
$gd2 = in_array('imagecreatetruecolor', $testGD) && function_exists('imagecreatetruecolor');
unset($testGD);
// The amount of pixels inbetween characters.
$character_spacing = 1;
// The color of the characters shown (red, green, blue).
$foreground_color = array(64, 101, 136);
$background_color = array(236, 237, 243);
// Has the theme author requested a custom color?
if (isset($settings['verification_foreground'], $settings['verification_background']))
{
$foreground_color = $settings['verification_foreground'];
$background_color = $settings['verification_background'];
}
if (!is_dir($settings['default_theme_dir'] . '/fonts'))
return false;
// Get a list of the available fonts.
$font_dir = dir($settings['default_theme_dir'] . '/fonts');
$font_list = array();
$ttfont_list = array();
while ($entry = $font_dir->read())
{
if (preg_match('~^(.+)\.gdf$~', $entry, $matches) === 1)
$font_list[] = $entry;
elseif (preg_match('~^(.+)\.ttf$~', $entry, $matches) === 1)
$ttfont_list[] = $entry;
}
if (empty($font_list))
return false;
// Create a list of characters to be shown.
$characters = array();
$loaded_fonts = array();
for ($i = 0; $i < strlen($code); $i++)
{
$characters[$i] = array(
'id' => $code{$i},
'font' => array_rand($font_list),
);
$loaded_fonts[$characters[$i]['font']] = null;
}
// Load all fonts and determine the maximum font height.
foreach ($loaded_fonts as $font_index => $dummy)
$loaded_fonts[$font_index] = imageloadfont($settings['default_theme_dir'] . '/fonts/' . $font_list[$font_index]);
// Determine the dimensions of each character.
$total_width = $character_spacing * strlen($code) + 10;
$max_height = 0;
foreach ($characters as $char_index => $character)
{
$characters[$char_index]['width'] = imagefontwidth($loaded_fonts[$character['font']]);
$characters[$char_index]['height'] = imagefontheight($loaded_fonts[$character['font']]);
$max_height = max($characters[$char_index]['height'], $max_height);
$total_width += $characters[$char_index]['width'];
}
// Create an image.
$code_image = imagecreate($total_width, $max_height);
// Draw the background.
$bg_color = imagecolorallocate($code_image, $background_color[0], $background_color[1], $background_color[2]);
imagefilledrectangle($code_image, 0, 0, $total_width - 1, $max_height - 1, $bg_color);
// Randomize the foreground color a little.
for ($i = 0; $i < 3; $i++)
$foreground_color[$i] = rand(max($foreground_color[$i] - 3, 0), min($foreground_color[$i] + 3, 255));
$fg_color = imagecolorallocate($code_image, $foreground_color[0], $foreground_color[1], $foreground_color[2]);
// Color for the dots.
for ($i = 0; $i < 3; $i++)
$dotbgcolor[$i] = $background_color[$i] < $foreground_color[$i] ? rand(0, max($foreground_color[$i] - 20, 0)) : rand(min($foreground_color[$i] + 20, 255), 255);
$randomness_color = imagecolorallocate($code_image, $dotbgcolor[0], $dotbgcolor[1], $dotbgcolor[2]);
// Fill in the characters.
$cur_x = 0;
foreach ($characters as $char_index => $character)
{
// Can we use true type fonts?
$can_do_ttf = function_exists('imagettftext');
if (!empty($can_do_ttf))
{
// GD2 handles font size differently.
$font_size = $gd2 ? rand(15, 18) : rand(18, 25);
// Work out the sizes - also fix the character width cause TTF not quite so wide!
$font_x = $cur_x + 5;
$font_y = $max_height - rand(2, 8);
// What font face?
if (!empty($ttfont_list))
{
$fontface = $settings['default_theme_dir'] . '/fonts/' . $ttfont_list[rand(0, count($ttfont_list) - 1)];
//log_error($fontface);
}
// What color are we to do it in?
$is_reverse = rand(0, 1);
$char_color = imagecolorallocate($code_image, rand(max($foreground_color[0] - 2, 0), $foreground_color[0]), rand(max($foreground_color[1] - 2, 0), $foreground_color[1]), rand(max($foreground_color[2] - 2, 0), $foreground_color[2]));
$angle = rand(-100, 100) / 10;
$show_letter = rand(0, 1) ? $character['id'] : strtolower($character['id']);
$fontcord = @imagettftext($code_image, 18, $angle, $font_x, $font_y, $char_color, $fontface, $show_letter);
if (empty($fontcord))
$can_do_ttf = false;
elseif ($is_reverse)
{
imagefilledpolygon($code_image, $fontcord, 4, $fg_color);
// Put the character back!
imagettftext($code_image, 18, $angle, $font_x, $font_y, $randomness_color, $fontface, $show_letter);
}
if ($can_do_ttf)
$cur_x = max($fontcord[2], $fontcord[4]) + 3;
}
if (!$can_do_ttf)
{
// Rotating the characters a little...
if (function_exists('imagerotate'))
{
$char_image = function_exists('imagecreatetruecolor') ? imagecreatetruecolor($character['width'], $character['height']) : imagecreate($character['width'], $character['height']);
$char_bgcolor = imagecolorallocate($char_image, $background_color[0], $background_color[1], $background_color[2]);
imagefilledrectangle($char_image, 0, 0, $character['width'] - 1, $character['height'] - 1, $char_bgcolor);
imagechar($char_image, $loaded_fonts[$character['font']], 0, 0, $character['id'], imagecolorallocate($char_image, rand(max($foreground_color[0] - 2, 0), $foreground_color[0]), rand(max($foreground_color[1] - 2, 0), $foreground_color[1]), rand(max($foreground_color[2] - 2, 0), $foreground_color[2])));
$rotated_char = imagerotate($char_image, rand(-100, 100) / 10, $char_bgcolor);
imagecopy($code_image, $rotated_char, $cur_x, 0, 0, 0, $character['width'], $character['height']);
imagedestroy($rotated_char);
imagedestroy($char_image);
}
// Sorry, no rotation available.
else
imagechar($code_image, $loaded_fonts[$character['font']], $cur_x, floor(($max_height - $character['height']) / 2), $character['id'], imagecolorallocate($code_image, rand(max($foreground_color[0] - 2, 0), $foreground_color[0]), rand(max($foreground_color[1] - 2, 0), $foreground_color[1]), rand(max($foreground_color[2] - 2, 0), $foreground_color[2])));
$cur_x += $character['width'] + $character_spacing;
}
}
// Make the background color transparent.
imagecolortransparent($code_image, $bg_color);
// Add some randomness to the background.
for ($i = rand(0, 2); $i < $max_height; $i += rand(1, 2))
for ($j = rand(0, 10); $j < $total_width; $j += rand(1, 15))
imagesetpixel($code_image, $j, $i, rand(0, 1) ? $fg_color : $randomness_color);
// Put in some lines too.
$num_lines = 2;
for ($i = 0; $i < $num_lines; $i++)
{
if (rand(0, 1))
{
$x1 = rand(0, $total_width);
$x2 = rand(0, $total_width);
$y1 = 0; $y2 = $max_height;
}
else
{
$y1 = rand(0, $max_height);
$y2 = rand(0, $max_height);
$x1 = 0; $x2 = $total_width;
}
imageline($code_image, $x1, $y1, $x2, $y2, rand (0, 1) ? $fg_color : $randomness_color);
}
// Show the image.
if (function_exists('imagegif'))
{
header('Content-type: image/gif');
imagegif($code_image);
}
else
{
header('Content-type: image/png');
imagepng($code_image);
}
// Bail out.
imagedestroy($code_image);
die();
}
// Create a letter for the visual verification code.
function showLetterImage($letter)
{
global $settings;
if (!is_dir($settings['default_theme_dir'] . '/fonts'))
return false;
// Get a list of the available font directories.
$font_dir = dir($settings['default_theme_dir'] . '/fonts');
$font_list = array();
while ($entry = $font_dir->read())
if ($entry{0} !== '.' && is_dir($settings['default_theme_dir'] . '/fonts/' . $entry) && file_exists($settings['default_theme_dir'] . '/fonts/' . $entry . '.gdf'))
$font_list[] = $entry;
if (empty($font_list))
return false;
// Pick a random font.
$random_font = $font_list[array_rand($font_list)];
// Check if the given letter exists.
if (!file_exists($settings['default_theme_dir'] . '/fonts/' . $random_font . '/' . $letter . '.gif'))
return false;
// Include it!
header('Content-type: image/gif');
include($settings['default_theme_dir'] . '/fonts/' . $random_font . '/' . $letter . '.gif');
This should be it.