123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- <?php
- defined('IN_IA') or exit('Access Denied');
- class Captcha {
- public $maxAngle = 15;
- public $maxOffset = 5;
- public $phrase = '';
-
- public function build($width, $height) {
- $image = @imagecreatetruecolor($width, $height);
- if(empty($image)) {
- return error('1', 'Not supplied GD');
- }
- $bg = imagecolorallocate($image, $this->rand(200, 255), $this->rand(200, 255), $this->rand(200, 255));
- imagefill($image, 0, 0, $bg);
-
- $square = $width * $height * 3;
- $effects = $this->rand($square/2000, $square/1000);
- for ($e = 0; $e < $effects; $e++) {
- $this->drawLine($image, $width, $height);
- }
- $this->phrase = $this->phrase();
- $color = $this->writePhrase($image, $this->phrase, $this->font(), $width, $height);
-
- $square = $width * $height;
- $effects = $this->rand($square/3000, $square/2000);
- if ($this->maxFrontLines !== 0) {
- for ($e = 0; $e < $effects; $e++) {
- $this->drawLine($image, $width, $height, $color);
- }
- }
-
- $image = $this->distort($image, $width, $height, $bg);
- $this->image = $image;
- return $this;
- }
-
- public function output($quality = 90) {
- header('content-type: image/png');
- imagepng($this->image);
- imagedestroy($this->image);
- }
-
- protected function phrase() {
- return random(4, true);
- }
-
- protected function rand($min, $max) {
- mt_srand((double) microtime() * 1000000);
- return mt_rand($min, $max);
- }
-
- protected function drawLine($image, $width, $height, $tcol = null) {
- if ($tcol === null) {
- $tcol = imagecolorallocate($image, $this->rand(100, 255), $this->rand(100, 255), $this->rand(100, 255));
- }
-
- if ($this->rand(0, 1)) { $Xa = $this->rand(0, $width/2);
- $Ya = $this->rand(0, $height);
- $Xb = $this->rand($width/2, $width);
- $Yb = $this->rand(0, $height);
- } else { $Xa = $this->rand(0, $width);
- $Ya = $this->rand(0, $height/2);
- $Xb = $this->rand(0, $width);
- $Yb = $this->rand($height/2, $height);
- }
- imagesetthickness($image, $this->rand(1, 3));
- imageline($image, $Xa, $Ya, $Xb, $Yb, $tcol);
- }
-
- protected function writePhrase($image, $phrase, $font, $width, $height) {
- $size = $width / strlen($phrase) - $this->rand(0, 3) - 1;
- $box = imagettfbbox($size, 0, $font, $phrase);
- $textWidth = $box[2] - $box[0];
- $textHeight = $box[1] - $box[7];
- $x = ($width - $textWidth) / 2;
- $y = ($height - $textHeight) / 2 + $size;
-
- $textColor = array($this->rand(0, 150), $this->rand(0, 150), $this->rand(0, 150));
- $col = imagecolorallocate($image, $textColor[0], $textColor[1], $textColor[2]);
-
- $length = strlen($phrase);
- for ($i=0; $i<$length; $i++) {
- $box = imagettfbbox($size, 0, $font, $phrase[$i]);
- $w = $box[2] - $box[0];
- $angle = $this->rand(-$this->maxAngle, $this->maxAngle);
- $offset = $this->rand(-$this->maxOffset, $this->maxOffset);
- imagettftext($image, $size, $angle, $x, $y + $offset, $col, $font, $phrase[$i]);
- $x += $w;
- }
- return $col;
- }
-
- public function distort($image, $width, $height, $bg) {
- $contents = imagecreatetruecolor($width, $height);
- $X = $this->rand(0, $width);
- $Y = $this->rand(0, $height);
- $phase = $this->rand(0, 10);
- $scale = 1.1 + $this->rand(0, 10000) / 30000;
- for ($x = 0; $x < $width; $x++) {
- for ($y = 0; $y < $height; $y++) {
- $Vx = $x - $X;
- $Vy = $y - $Y;
- $Vn = sqrt($Vx * $Vx + $Vy * $Vy);
-
- if ($Vn != 0) {
- $Vn2 = $Vn + 4 * sin($Vn / 30);
- $nX = $X + ($Vx * $Vn2 / $Vn);
- $nY = $Y + ($Vy * $Vn2 / $Vn);
- } else {
- $nX = $X;
- $nY = $Y;
- }
- $nY = $nY + $scale * sin($phase + $nX * 0.2);
- $p = $this->interpolate(
- $nX - floor($nX),
- $nY - floor($nY),
- $this->getCol($image, floor($nX), floor($nY), $bg),
- $this->getCol($image, ceil($nX), floor($nY), $bg),
- $this->getCol($image, floor($nX), ceil($nY), $bg),
- $this->getCol($image, ceil($nX), ceil($nY), $bg)
- );
-
- if ($p == 0) {
- $p = $bg;
- }
-
- imagesetpixel($contents, $x, $y, $p);
- }
- }
-
- return $contents;
- }
-
- protected function interpolate($x, $y, $nw, $ne, $sw, $se) {
- list($r0, $g0, $b0) = $this->getRGB($nw);
- list($r1, $g1, $b1) = $this->getRGB($ne);
- list($r2, $g2, $b2) = $this->getRGB($sw);
- list($r3, $g3, $b3) = $this->getRGB($se);
-
- $cx = 1.0 - $x;
- $cy = 1.0 - $y;
-
- $m0 = $cx * $r0 + $x * $r1;
- $m1 = $cx * $r2 + $x * $r3;
- $r = (int) ($cy * $m0 + $y * $m1);
-
- $m0 = $cx * $g0 + $x * $g1;
- $m1 = $cx * $g2 + $x * $g3;
- $g = (int) ($cy * $m0 + $y * $m1);
-
- $m0 = $cx * $b0 + $x * $b1;
- $m1 = $cx * $b2 + $x * $b3;
- $b = (int) ($cy * $m0 + $y * $m1);
-
- return ($r << 16) | ($g << 8) | $b;
- }
-
- protected function getRGB($col) {
- return array(
- (int) ($col >> 16) & 0xff,
- (int) ($col >> 8) & 0xff,
- (int) ($col) & 0xff,
- );
- }
-
- protected function getCol($image, $x, $y, $background) {
- $L = imagesx($image);
- $H = imagesy($image);
- if ($x < 0 || $x >= $L || $y < 0 || $y >= $H) {
- return $background;
- }
-
- return imagecolorat($image, $x, $y);
- }
-
- protected function font() {
- return IA_ROOT . '/web/resource/fonts/captcha.ttf';
- }
- }
- ?>
|