{
// r,g,b values are from 0 to 1
// h = [0,360], s = [0,1], v = [0,1]
// if s == 0, then h = -1 (undefined)
$tmp = min($R, $G);
$min = min($tmp, $B);
$tmp = max($R, $G);
$max = max($tmp, $B);
$V = $max;
$delta = $max - $min;
if($max != 0)
$S = $delta / $max; // s
else
{
$S = 0;
//$H = UNDEFINEDCOLOR;
return;
}
if($R == $max)
$H = ($G - $B) / $delta; // between yellow & magenta
else if($G == $max)
$H = 2 + ($B - $R) / $delta; // between cyan & yellow
else
$H = 4 + ($R - $G) / $delta; // between magenta & cyan
$H *= 60; // degrees
if($H < 0)
$H += 360;
return array($H, $S, $V);
}
function HsvToRgb($H, $S, $V)
{
if($S == 0)
{
// achromatic (grey)
$R = $G = $B = $V;
return;
}
$H /= 60; // sector 0 to 5
$i = floor($H);
$f = $H - $i; // factorial part of h
$p = $V * (1 - $S);
$q = $V * (1 - $S * $f);
$t = $V * (1 - $S * (1 - $f));
switch($i)
{
case 0:
$R = $V;
$G = $t;
$B = $p;
break;
case 1:
$R = $q;
$G = $V;
$B = $p;
break;
case 2:
$R = $p;
$G = $V;
$B = $t;
break;
case 3:
$R = $p;
$G = $q;
$B = $V;
break;
case 4:
$R = $t;
$G = $p;
$B = $V;
break;
default: // case 5:
$R = $V;
$G = $p;
$B = $q;
break;
}
return array($R, $G, $B);
}
$size = 20;
$width = 80;
$height = 25;
// 產生4個隨機字符
$randStr =array(rand(0, 9), rand(0, 9), rand(0, 9), rand(0, 9));
// 生成數字旋轉角度
$degrees = array(rand(0, 45), rand(0, 45), rand(0, 45), rand(0, 45));
for($i = 0; $i < 4; ++$i)
{
if(rand() % 2);
else $degrees[$i] = -$degrees[$i];
}
$image = imagecreatetruecolor($size, $size); // 數字圖片畫布
$validate = imagecreatetruecolor($width, $height); // 最終驗證碼畫布
$back = imagecolorallocate($image, 255, 255, 255); // 背景色
$border = imagecolorallocate($image, 0, 0, 0); // 邊框
// 數字顏色
for($i = 0; $i < 4; ++$i)
{
// 考慮爲使字符容易看清使用顏色較暗的顏色
$temp = RgbToHsv(rand(0, 255), rand(0, 255), rand(0, 255));
if($temp[2] > 60)
$temp [2] = 60;
$temp = HsvToRgb($temp[0], $temp[1], $temp[2]);
$textcolor[$i] = imagecolorallocate($image, $temp[0], $temp[1], $temp[2]);
}
imagefilledrectangle($validate, 0, 0, $width - 1, $height - 1, $back); // 畫出背景色
imagefilledrectangle($image, 0, 0, $size, $size, $back); // 畫出背景色
imagestring($image, 5, 6, 2, $randStr[0], $textcolor[0]); // 畫出數字
$image = imagerotate($image, $degrees[0], $back);
imagecopy($validate, $image, 1, 4, 4, 5, imagesx($image) - 10, imagesy($image) - 10);
$image = imagecreatetruecolor($size, $size);
imagefilledrectangle($image, 0, 0, $size, $size, $back); // 畫出背景色
imagestring($image, 5, 6, 2, $randStr[1], $textcolor[1]); // 畫出數字
$image = imagerotate($image, $degrees[1], $back);
imagecopy($validate, $image, 21, 4, 4, 5, imagesx($image) - 10, imagesy($image) - 10);
$image = imagecreatetruecolor($size, $size);
imagefilledrectangle($image, 0, 0, $size - 1, $size - 1, $back); // 畫出背景色
imagestring($image, 5, 6, 2, $randStr[2], $textcolor[2]); // 畫出數字
$image = imagerotate($image, $degrees[2], $back);
imagecopy($validate, $image, 41, 4, 4, 5, imagesx($image) - 10, imagesy($image) - 10);
$image = imagecreatetruecolor($size, $size);
imagefilledrectangle($image, 0, 0, $size - 1, $size - 1, $back); // 畫出背景色
imagestring($image, 5, 6, 2, $randStr[3], $textcolor[3]); // 畫出數字
$image = imagerotate($image, $degrees[3], $back);
imagecopy($validate, $image, 61, 4, 4, 5, imagesx($image) - 10, imagesy($image) - 10);
imagerectangle($validate, 0, 0, $width - 1, $height - 1, $border); // 畫出邊框
for($i = 0; $i < 200; ++$i) //加入干擾象素
{
$randpixelcolor = ImageColorallocate($validate, rand(0, 255), rand(0, 255), rand(0, 255));
imagesetpixel($validate, rand(1, 87), rand(1, 27), $randpixelcolor);
}
// 干擾線使用顏色較明亮的顏色
$temp = RgbToHsv(rand(0, 255), rand(0, 255), rand(0, 255));
if($temp[2] < 200)
$temp [2] = 255;
$temp = HsvToRgb($temp[0], $temp[1], $temp[2]);
$randlinecolor = imagecolorallocate($image, $temp[0], $temp[1], $temp[2]);
// 畫5條幹擾線
for ($i = 0;$i < 5; $i ++)
imageline($validate, rand(1, 79), rand(1, 24), rand(1, 79), rand(1, 24), $randpixelcolor);
header('Content-type: image/png');
imagepng($validate);
imagedestroy($validate);
最後討論一下新浪博客中的“收聽驗證碼”,呵呵,看起來好像很複雜,考慮了一下,其實要實現也挺簡單的,將單個數字錄成mp3格式的聲音文件,使用windows media player根據產生的數字播放出來(網頁中嵌入個object)。考慮兼容問題最好使用flash播放。
提示一下:程序中有Rgb到Hsv顏色互換函數。