123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- <?php
- /**
- * Require Image_Text class for generating the text.
- *
- * PHP version 5
- *
- * @category Text
- * @package Text_CAPTCHA
- * @author Christian Wenz <wenz@php.net>
- * @author Michael Cramer <michael@bigmichi1.de>
- * @license http://www.opensource.org/licenses/bsd-license.php BSD License
- * @link http://pear.php.net/package/Text_CAPTCHA
- */
- /**
- * Text_CAPTCHA_Driver_Image - Text_CAPTCHA driver graphical CAPTCHAs
- *
- * Class to create a graphical Turing test
- *
- * @category Text
- * @package Text_CAPTCHA
- * @author Christian Wenz <wenz@php.net>
- * @author Michael Cramer <michael@bigmichi1.de>
- * @license http://www.opensource.org/licenses/bsd-license.php BSD License
- * @link http://pear.php.net/package/Text_CAPTCHA
- * @todo refine the obfuscation algorithm :-)
- * @todo consider removing Image_Text dependency
- */
- class Text_CAPTCHA_Driver_Image extends Text_CAPTCHA_Driver_Base
- {
- /**
- * Text_Password options.
- *
- * @var array
- */
- private $_textPasswordOptions;
- /**
- * Width of CAPTCHA
- *
- * @var int
- */
- private $_width;
- /**
- * Height of CAPTCHA
- *
- * @var int
- */
- private $_height;
- /**
- * CAPTCHA output format
- *
- * @var string
- */
- private $_output;
- /**
- * Further options (here: for Image_Text)
- *
- * @var array
- */
- private $_imageOptions = array(
- 'font_size' => 24,
- 'font_path' => './',
- 'font_file' => 'COUR.TTF',
- 'text_color' => '#000000',
- 'lines_color' => '#CACACA',
- 'background_color' => '#555555',
- 'antialias' => false
- );
- /**
- * Init function
- *
- * Initializes the new Text_CAPTCHA_Driver_Image object and creates a GD image
- *
- * @param array $options CAPTCHA options
- *
- * @return void
- */
- public function initDriver($options = array())
- {
- if (is_array($options)) {
- if (isset($options['width']) && is_int($options['width'])) {
- $this->_width = $options['width'];
- } else {
- $this->_width = 200;
- }
- if (isset($options['height']) && is_int($options['height'])) {
- $this->_height = $options['height'];
- } else {
- $this->_height = 80;
- }
- if (!isset($options['phrase']) || empty($options['phrase'])) {
- $phraseOptions = (isset($options['phraseOptions'])
- && is_array($options['phraseOptions']))
- ? $options['phraseOptions'] : array();
- $this->_textPasswordOptions = $phraseOptions;
- } else {
- $this->setPhrase($options['phrase']);
- }
- if (!isset($options['output']) || empty($options['output'])) {
- $this->_output = 'jpeg';
- } else {
- $this->_output = $options['output'];
- }
- if (isset($options['imageOptions'])
- && is_array($options['imageOptions'])
- && count($options['imageOptions']) > 0
- ) {
- $this->_imageOptions = array_merge(
- $this->_imageOptions, $options['imageOptions']
- );
- }
- }
- }
- /**
- * Create CAPTCHA image.
- *
- * This method creates a CAPTCHA image.
- *
- * @return void
- * @throws Text_CAPTCHA_Exception when image generation with Image_Text produces
- * an error
- */
- public function createCAPTCHA()
- {
- $options['canvas'] = array(
- 'width' => $this->_width,
- 'height' => $this->_height
- );
- $options['width'] = $this->_width - 20;
- $options['height'] = $this->_height - 20;
- $options['cx'] = ceil(($this->_width) / 2 + 10);
- $options['cy'] = ceil(($this->_height) / 2 + 10);
- $options['angle'] = rand(0, 30) - 15;
- $options['font_size'] = $this->_imageOptions['font_size'];
- $options['font_path'] = $this->_imageOptions['font_path'];
- $options['font_file'] = $this->_imageOptions['font_file'];
- $options['color'] = array($this->_imageOptions['text_color']);
- $options['background_color'] = $this->_imageOptions['background_color'];
- $options['max_lines'] = 1;
- $options['mode'] = 'auto';
- do {
- $imageText = new Image_Text($this->getPhrase(), $options);
- $imageText->init();
- $result = $imageText->measurize();
- } while ($result === false && --$options['font_size'] > 0);
- if ($result === false) {
- throw new Text_CAPTCHA_Exception(
- 'The text provided does not fit in the image dimensions'
- );
- }
- $imageText->render();
- $image = $imageText->getImg();
- if ($this->_imageOptions['antialias'] && function_exists('imageantialias')) {
- imageantialias($image, true);
- }
- $colors = Image_Text::convertString2RGB(
- $this->_imageOptions['lines_color']
- );
- $linesColor = imagecolorallocate(
- $image, $colors['r'], $colors['g'], $colors['b']
- );
- //some obfuscation
- for ($i = 0; $i < 3; $i++) {
- $x1 = rand(0, $this->_width - 1);
- $y1 = rand(0, round($this->_height / 10, 0));
- $x2 = rand(0, round($this->_width / 10, 0));
- $y2 = rand(0, $this->_height - 1);
- imageline($image, $x1, $y1, $x2, $y2, $linesColor);
- $x1 = rand(0, $this->_width - 1);
- $y1 = $this->_height - rand(1, round($this->_height / 10, 0));
- $x2 = $this->_width - rand(1, round($this->_width / 10, 0));
- $y2 = rand(0, $this->_height - 1);
- imageline($image, $x1, $y1, $x2, $y2, $linesColor);
- $cx = rand(0, $this->_width - 50) + 25;
- $cy = rand(0, $this->_height - 50) + 25;
- $w = rand(1, 24);
- imagearc($image, $cx, $cy, $w, $w, 0, 360, $linesColor);
- }
- // @todo remove hardcoded value
- $this->_output = 'jpg';
- if ($this->_output == 'gif' && imagetypes() & IMG_GIF) {
- $this->setCaptcha($this->_getCAPTCHAAsGIF($image));
- } else if (($this->_output == 'jpg' && imagetypes() & IMG_JPG)
- || ($this->_output == 'jpeg' && imagetypes() & IMG_JPEG)
- ) {
- $this->setCaptcha($this->_getCAPTCHAAsJPEG($image));
- } else if ($this->_output == 'png' && imagetypes() & IMG_PNG) {
- $this->setCaptcha($this->_getCAPTCHAAsPNG($image));
- } else if ($this->_output == 'resource') {
- $this->setCaptcha($image);
- } else {
- throw new Text_CAPTCHA_Exception(
- "Unknown or unsupported output type specified"
- );
- }
- imagedestroy($image);
- }
- /**
- * Return CAPTCHA as PNG.
- *
- * This method returns the CAPTCHA as PNG.
- *
- * @param resource $image generated image
- *
- * @return string image contents
- */
- private function _getCAPTCHAAsPNG($image)
- {
- ob_start();
- imagepng($image);
- $data = ob_get_contents();
- ob_end_clean();
- return $data;
- }
- /**
- * Return CAPTCHA as JPEG.
- *
- * This method returns the CAPTCHA as JPEG.
- *
- * @param resource $image generated image
- *
- * @return string image contents
- */
- private function _getCAPTCHAAsJPEG($image)
- {
- ob_start();
- imagejpeg($image);
- $data = ob_get_contents();
- ob_end_clean();
- return $data;
- }
- /**
- * Return CAPTCHA as GIF.
- *
- * This method returns the CAPTCHA as GIF.
- *
- * @param resource $image generated image
- *
- * @return string image contents
- */
- private function _getCAPTCHAAsGIF($image)
- {
- ob_start();
- imagegif($image);
- $data = ob_get_contents();
- ob_end_clean();
- return $data;
- }
- /**
- * Create random CAPTCHA phrase, Image edition (with size check).
- *
- * This method creates a random phrase, maximum 8 characters or width / 25,
- * whatever is smaller.
- *
- * @return void
- */
- public function createPhrase()
- {
- $len = intval(min(8, $this->_width / 25));
- $options = $this->_textPasswordOptions;
- $textPassword = new Text_Password();
- if (!is_array($options) || count($options) === 0) {
- $this->setPhrase($textPassword->create($len));
- } else {
- if (count($options) === 1) {
- $this->setPhrase($textPassword->create($len, $options[0]));
- } else {
- $this->setPhrase(
- $textPassword->create($len, $options[0], $options[1])
- );
- }
- }
- }
- }
|