www.gusucode.com > 3D验证码 1.0.0php源码程序 > 3dCaptcha-1.0.0/3dCaptcha-1.0.0/src/3DCaptcha.php
<? /** * 3D Captcha * (C) 2006 by Marc S. Ressl */ // Get captcha text session_start(); $captchaText = $_SESSION['3DCaptchaText']; // Functions function addVector($a, $b) { return array($a[0] + $b[0], $a[1] + $b[1], $a[2] + $b[2]); } function scalarProduct($vector, $scalar) { return array($vector[0] * $scalar, $vector[1] * $scalar, $vector[2] * $scalar); } function dotProduct($a, $b) { return ($a[0] * $b[0] + $a[1] * $b[1] + $a[2] * $b[2]); } function norm($vector) { return sqrt(dotProduct($vector, $vector)); } function normalize($vector) { return scalarProduct($vector, 1 / norm($vector)); } // http://en.wikipedia.org/wiki/Cross_product function crossProduct($a, $b) { return array( ($a[1] * $b[2] - $a[2] * $b[1]), ($a[2] * $b[0] - $a[0] * $b[2]), ($a[0] * $b[1] - $a[1] * $b[0]) ); } function vectorProductIndexed($v, $m, $i) { return array( $v[$i + 0] * $m[0] + $v[$i + 1] * $m[4] + $v[$i + 2] * $m[8] + $v[$i + 3] * $m[12], $v[$i + 0] * $m[1] + $v[$i + 1] * $m[5] + $v[$i + 2] * $m[9] + $v[$i + 3] * $m[13], $v[$i + 0] * $m[2] + $v[$i + 1] * $m[6] + $v[$i + 2] * $m[10]+ $v[$i + 3] * $m[14], $v[$i + 0] * $m[3] + $v[$i + 1] * $m[7] + $v[$i + 2] * $m[11]+ $v[$i + 3] * $m[15] ); } function vectorProduct($v, $m) { return vectorProductIndexed($v, $m, 0); } function matrixProduct($a, $b) { $o1 = vectorProductIndexed($a, $b, 0); $o2 = vectorProductIndexed($a, $b, 4); $o3 = vectorProductIndexed($a, $b, 8); $o4 = vectorProductIndexed($a, $b, 12); return array( $o1[0], $o1[1], $o1[2], $o1[3], $o2[0], $o2[1], $o2[2], $o2[3], $o3[0], $o3[1], $o3[2], $o3[3], $o4[0], $o4[1], $o4[2], $o4[3] ); } // http://graphics.idav.ucdavis.edu/education/GraphicsNotes/Camera-Transform/Camera-Transform.html function cameraTransform($C, $A) { $w = normalize(addVector($C, scalarProduct($A, -1))); $y = array(0, 1, 0); $u = normalize(crossProduct($y, $w)); $v = crossProduct($w, $u); $t = scalarProduct($C, -1); return array( $u[0], $v[0], $w[0], 0, $u[1], $v[1], $w[1], 0, $u[2], $v[2], $w[2], 0, dotProduct($u, $t), dotProduct($v, $t), dotProduct($w, $t), 1 ); } // http://graphics.idav.ucdavis.edu/education/GraphicsNotes/Viewing-Transformation/Viewing-Transformation.html function viewingTransform($fov, $n, $f) { $fov *= (M_PI / 180); $cot = 1 / tan($fov / 2); return array( $cot, 0, 0, 0, 0, $cot, 0, 0, 0, 0, ($f + $n) / ($f - $n), -1, 0, 0, 2 * $f * $n / ($f - $n), 0 ); } // 3dcha parameters $fontsize = 24; $fontfile = '3DCaptcha.ttf'; $details = imagettfbbox($fontsize, 0, $fontfile, $captchaText); $image2d_x = $details[4] + 4; $image2d_y = $fontsize * 1.3; $bevel = 4; // Create 2d image $image2d = imagecreatetruecolor($image2d_x, $image2d_y); $black = imagecolorallocate($image2d, 0, 0, 0); $white = imagecolorallocate($image2d, 255, 255, 255); // Paint 2d image imagefill($image2d, 0, 0, $black); imagettftext($image2d, $fontsize, 0, 2, $fontsize, $white, $fontfile, $captchaText); // Calculate projection matrix $T = cameraTransform( array(rand(-90, 90), -200, rand(150, 250)), array(0, 0, 0) ); $T = matrixProduct( $T, viewingTransform(60, 300, 3000) ); // Calculate coordinates $coord = array($image2d_x * $image2d_y); $count = 0; for ($y = 0; $y < $image2d_y; $y+=2) { for ($x = 0; $x < $image2d_x; $x++) { // calculate x1, y1, x2, y2 $xc = $x - $image2d_x / 2; $zc = $y - $image2d_y / 2; $yc = -(imagecolorat($image2d, $x, $y) & 0xff) / 256 * $bevel; $xyz = array($xc, $yc, $zc, 1); $xyz = vectorProduct($xyz, $T); $coord[$count] = $xyz; $count++; } } // Create 3d image $image3d_x = 256; //$image3d_y = $image3d_x / 1.618; $image3d_y = $image3d_x * 9 / 16; $image3d = imagecreatetruecolor($image3d_x, $image3d_y); $fgcolor = imagecolorallocate($image3d, 255, 255, 255); $bgcolor = imagecolorallocate($image3d, 0, 0, 0); imageantialias($image3d, true); imagefill($image3d, 0, 0, $bgcolor); $count = 0; $scale = 1.75 - $image2d_x/400; for ($y = 0; $y < $image2d_y; $y++) { for ($x = 0; $x < $image2d_x; $x++) { if ($x > 0) { $x0 = $coord[$count - 1][0] * $scale + $image3d_x / 2; $y0 = $coord[$count - 1][1] * $scale + $image3d_y / 2; $x1 = $coord[$count][0] * $scale + $image3d_x / 2; $y1 = $coord[$count][1] * $scale + $image3d_y / 2; imageline($image3d, $x0, $y0, $x1, $y1, $fgcolor); } $count++; } } header("Content-type: image/jpeg"); header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 header("Expires: Mon, 03 Apr 1977 11:05:00 GMT"); // Date in the very past, guess what it is imagejpeg($image3d); ?>