- 首先创建画布并为其设置背景色。
- 完成干扰元素(点和线)的绘制。
- 完成验证码图片边框的绘制。
- 完成验证码码值的获取以及颜色、大小等相关计算。
- 完成验证码的绘制及输出。
/**
* 生成验证码
* @param int $w 验证码图片的宽度
* @param int $h 验证码图片的高度
* @param int $len 验证码码值的长度
* @param int $font 验证码字体大小
*/
function captcha($w = 100, $h = 50, $len = 5, $font = 5)
{
$img = @imagecreatetruecolor($w, $h) or die('Cannot Initialize new GD image stream'); // 生成画布
$bg_color = imagecolorallocate($img, 0xcc, 0xcc, 0xcc); // 生成背景颜色
imagefill($img, 0, 0, $bg_color); // 设置背景色
// 绘制干扰像素(点)
for ($i = 0; $i <= 200; ++$i) {
$color = imagecolorallocate($img, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
imagesetpixel($img, mt_rand(0, $w), mt_rand(0, $h), $color);
}
// 绘制干扰线
for ($i = 0; $i <= 8; ++$i) {
$color = imagecolorallocate($img, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
imageline($img, mt_rand(0, $w), mt_rand(0, $h), mt_rand(0, $w), mt_rand(0, $h), $color);
}
// 绘制图片矩形边框
$rect_color = imagecolorallocate($img, 0x90, 0x90, 0x90);
imagerectangle($img, 0, 0, $w - 1, $h - 1, $rect_color);
// 生成码值数组,不需要0,避免与字母o冲突
$char = array_merge(range('A', 'Z'), range('a', 'z'), range(1, 9));
//随机获取$len个码值的键,并保证是数组
$rand_keys = (array) array_rand($char, $len);
// 打乱随机获取的码值键的数组
shuffle($rand_keys);
//根据键获取对应的码值,并拼接成字符串
$VerificationCode = '';
foreach ($rand_keys as $key) {
$VerificationCode .= $char[$key];
}
//设定字符串颜色
$str_color = imagecolorallocate($img, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100));
//设定字符串位置
$font_w = imagefontwidth($font); // 字体宽
$font_h = imagefontheight($font); // 字体高
$str_w = $font_w * $len; // 字符串宽
imagestring($img, $font, ($w - $str_w) / 2, ($h - $font_h) / 2, $VerificationCode, $str_color);
header('Content-Type: image/png');
imagepng($img); // 输出图片内容
imagedestroy($img); // 销毁画布
}
可使用 imagettftext 函数替换imagestring 函数设置更大的字体
//可使用 imagettftext 函数替换imagestring 函数设置更大的字体
// $fontfile = 'C:/Windows/Fonts/arial.ttf';
// imagettftext($img , $font , 0 , $font_w , $font_h*2 , $str_color, $fontfile , $VerificationCode);
// //$w = 100, $h = 50, $len = 5, $font = 20
如果要制作中文验证码需要注意以下几个问题:
1.在 utf-8 编码下,汉字占3个字节
2. 绘制中文的函数是 imagettftext 函数 (ttf表示”ttf”字体文件)
3. 在绘制中文字符串的时候需要附带中文字体包(比如方正黑体)
/**
* 产生随机中文字符串
* @param string $strCN 中文字符串
* @param integer $len 返回的中文字符串个数 默认为4
* @return string 返回的随机中文字符串
*/
function randChinese($strCN , $len = 4)
{
$retStr = '';
//计算中文在utf-8编码下的字符数
$ChineseLen = strlen($strCN) / 3;
for($i = 0; $i < $len; $i++){
//随机截取中文字符
$pos = 3*mt_rand(0, $ChineseLen - 1);
$retStr .= substr($strCN, $pos,3);
}
return $retStr;
}