PHP Classes
elePHPant
Icontem

File: captcha_numbersV2.php

Recommend this page to a friend!
  Classes of Albert Demeter  >  Captcha Numbers V2.1  >  captcha_numbersV2.php  >  Download  
File: captcha_numbersV2.php
Role: Class source
Content type: text/plain
Description: Main Class
Class: Captcha Numbers V2.1
Generate CAPTCHA validation images
Author: By
Last change: - updated class to work with PHP 7.x version
- modified image size
- fixed TTF problem (if imagettftext function is not supported then imagechar is used to display text on image)
- added letter spacing
- added random y position for chars
- improved random font selection
- modified grid display, now it displays random lines between min and max values
Date: 7 months ago
Size: 11,428 bytes
 

 

Contents

Class file image Download
<? 
/** 
* CaptchaV2 File 
* Generates CAPTCHA Numbers and Chars Image 
* @author Albert Demeter <borex8@hotmail.com> 
* @version 2.3 
* GNU General Public License (Version 2.3, March 14th, 2019) 
* 
* based on Hadar Porat's Captcha Numbers class v.1.5 <hpman28@gmail.com> 
* 
* This program is free software; you can redistribute 
* it and/or modify it under the terms of the GNU 
* General Public License as published by the Free 
* Software Foundation; either version 2 of the License, 
* or (at your option) any later version. 
* 
* This program is distributed in the hope that it will 
* be useful, but WITHOUT ANY WARRANTY; without even the 
* implied warranty of MERCHANTABILITY or FITNESS FOR A 
* PARTICULAR PURPOSE. See the GNU General Public License 
* for more details. 
*/ 

/** 
* CaptchaNumbersV2 Class 
* @access public 
* @author Albert Demeter <borex8@hotmail.com> 
* @version 2.0 
*/ 

class CaptchaNumbersV2 { 
    var $length = 6; 
    var $type = 'png'; 
    var $height = 60; 
    var $width = 160; 
    var $string = ''; 
    var $captchaType = 'mixed'; 
    
    // automatically calculated based on the percent in the constructor 
    var $dotsCount = 0; 
    
    // background colors RED, GREEN and BLUE values (provide it as a number between 0-255) 
    var $bgColorRed = 240; 
    var $bgColorGreen = 240; 
    var $bgColorBlue = 240; 
    
    // if true then grid is drawn 
    var $drawGrid = true; 
    
    // if true then every grid line will have a different color 
    var $randomGridColor = true; 
    
    // min number of grid lines to draw 
    var $min_number_of_grid_lines = 2; 
    
    // max number of grid lines to draw 
    var $max_number_of_grid_lines = 7; 

    // if true then every letter will have a different color 
    var $randomLetterColor = true; 

    // array of TTF fonts (path/filename)
    // fonts array to use for random char fonts
    var $fonts = [
        //'fonts/arial.ttf',
        //'fonts/vera.ttf',
    ];
    // fonts are loaded automatically from this folder
    var $fonts_folder = 'fonts/'; 
    // the range of font size of each letter displayed as pixels.
    var $font_size_min = 16; 
    var $font_size_max = 20; 
    // font angles are for placing the fonts at a random angle. high values of angles might have unexpected results. 
    var $font_angle_min = -15; 
    var $font_angle_max = 15; 

    /** 
    * @return void 
    * @param int $length string length 
    * @param String $type image type 
    * @param String $captchaType text contain digits, chars or mixed 
    * @param int $dotsPercent random pixels generated in image 
    * @desc generate the main image 
    */ 
    function __construct($length = '', $type = '', $captchaType = '', $dotsPercent = 10, $fonts_folder = '') { 
        if ($length!='') $this -> length = $length; 
        if ($type!='') $this -> type = $type; 
        if ($captchaType!='') $this -> captchaType = $captchaType; 
        if ($fonts_folder!='') $this -> fonts_folder = $fonts_folder; 

        $newWidth = $this -> length * $this -> font_size_max; 
        $newHeight = $this -> font_size_max; 
        if ($newWidth > $this -> width)
            $this -> width = $newWidth;
        if ($newHeight > $this -> height)
            $this -> height = $newHeight;
        
        if (!empty($this->fonts_folder) && file_exists($this->fonts_folder)) {
            foreach (glob($this->fonts_folder . "*.ttf") as $file) {
                if (!in_array($file, $this->fonts))
                    $this->fonts[] = $file;
            }
        }
        
        // dots count equals #% of all points in the image 
        $this -> dotsCount = round(($this -> width * $this -> height) * $dotsPercent / 100); 
        
        $this -> generateString(); 
    } 

    /** 
    * @return void 
    * @desc display captcha image 
    */ 
    function display() { 
        $this -> sendHeader(); 
        $image = $this -> generate(); 

        switch ($this-> type) { 
            case 'jpeg': imagejpeg($image); break; 
            case 'png': imagepng($image); break; 
            case 'gif': imagegif($image); break; 
            default: imagepng($image); break; 
        } 
    }
    
    // function picks a random font for each letter each time 
    function random_font() { 
        $font = null;
        if (count($this->fonts) > 0) {
            $rand = mt_rand(0, count($this->fonts)-1);
            $font = $this->fonts[$rand]; 
        }
        if (file_exists($font))
            return $font;
        else
            return null;
    } 
    
    // the font size would be determined randomly within the limits defined above. 
    function random_font_size() { 
        if ($this->font_size_min == $this->font_size_max)
            return $this->font_size_min;
        return mt_rand($this->font_size_min, $this->font_size_max); 
    } 
    
    // the angle would be determined randomly within the limits defined above. 
    function random_font_angle() { 
        if ($this->font_angle_min == $this->font_angle_max)
            return $this->font_angle_min;
        return mt_rand($this->font_angle_min, $this->font_angle_max); 
    } 
    
    /** 
    * @return Image 
    * @desc generate the image 
    */ 
    function generate() { 
        $image = ImageCreate($this -> width, $this -> height) or die("Cannot Initialize new GD image stream"); 
        
        // colors 
        $background_color = ImageColorAllocate($image, $this -> bgColorRed, $this -> bgColorGreen, $this -> bgColorBlue); 
        if (!$this -> randomLetterColor) 
        { 
          $net_color_1 = ImageColorAllocate($image, 10, 200, 10); 
          $net_color_2 = ImageColorAllocate($image, 200, 10, 10); 
        } 
        if (!$this -> randomLetterColor) 
        { 
          $stringcolor_1 = ImageColorAllocate($image, 150, 150, 150); 
          $stringcolor_2 = ImageColorAllocate($image, 120, 120, 250); 
        } 

        if ($this -> drawGrid) {
            $count = mt_rand($this->min_number_of_grid_lines, $this->max_number_of_grid_lines);
            for ($i = 0; $i < $count; $i++) { 
                if ($this -> randomGridColor) { 
                    $net_color_1 = ImageColorAllocate($image, mt_rand(0,255), mt_rand(0,250), mt_rand(0,250)); 
                    $net_color_2 = ImageColorAllocate($image, mt_rand(0,255), mt_rand(0,250), mt_rand(0,250)); 
                }
                
                if ($i%2) imageline($image, 0, mt_rand(0, $this->height), $this->width, mt_rand(0, $this->height), $net_color_1); 
                    else imageline($image, mt_rand(0, $this->width), 0, mt_rand(0, $this->width), $this->height, $net_color_2); 
            } 
        }

        // make the text 
        $str = $this -> getString(); 
        $x = 0; 
        for($i = 0, $n = strlen($str); $i < $n; $i++) 
        { 
          if ($this -> randomLetterColor) 
          { 
            $stringcolor_1 = ImageColorAllocate($image, mt_rand(0,255), mt_rand(0,250), mt_rand(0,250)); 
            $stringcolor_2 = ImageColorAllocate($image, mt_rand(0,255), mt_rand(0,250), mt_rand(0,250)); 
          } 
            $font = $this->random_font(); 
            $fontSize = $this->random_font_size(); 
            $fontAngle = $this->random_font_angle(); 
            $spacing = $this->width / $fontSize * $i;
            if (is_callable('imagettftext') && $font != null) {
                $y = ($this->height / 2) + ($fontSize / 2);
                $y += mt_rand(-1 * $y / 2, $y / 2);
                if ($i%2) imagettftext($image, $fontSize, $fontAngle, $x + $spacing, $y, $stringcolor_1, $font, $str{$i} ); 
                    else imagettftext($image, $fontSize, $fontAngle, $x + $spacing, $y, $stringcolor_2, $font, $str{$i} ); 
            } else {
                $y = ($this->height / 2);
                if ($i%2) imagechar($image, $fontSize, $x + $spacing, $y, $str{$i}, $stringcolor_1 );
                    else imagechar($image, $fontSize, $x + $spacing, $y, $str{$i}, $stringcolor_2 );
            }
            $x = $x + $fontSize; 
        } 
        
        for ($i = 0; $i < $this -> dotsCount; $i++) 
        { 
            $x = rand(0, $this -> width - 1); 
            $y = rand(0, $this -> height - 1); 
            $rgbIndex = imagecolorat($image, $x, $y); 
            $rgb = imagecolorsforindex($image, $rgbIndex); 
            //print $x . ' x ' . $y . ' : ' . $rgbIndex . '(' . $rgb['red'] . '-' . $rgb['green'] . '-' . $rgb['blue'] . ')<br>'; 

            // if background color create random pixel color 
            if ($rgb['red'] == $this -> bgColorRed 
                     && $rgb['green'] == $this -> bgColorGreen 
                    && $rgb['blue'] == $this -> bgColorBlue) 
            { 
                 $dotColor = ImageColorAllocate($image, mt_rand(0,255), mt_rand(0,255), mt_rand(0,255)); 
            } 
            else 
            { 
                 // not background color then generate a close shade color 
                $rgb['red'] = $rgb['red'] + ((mt_rand(0,100) % 2) == 1 ? 1 : -1) * mt_rand(0, 255 - $rgb['red']); 
                if ($rgb['red'] < 0 || $rgb['red'] > 255) $rgb['red'] = mt_rand(0, 255); 

                $rgb['green'] = $rgb['green'] + ((mt_rand(0,100) % 2) == 1 ? 1 : -1) * mt_rand(0, 255 - $rgb['green']); 
                if ($rgb['green'] < 0 || $rgb['green'] > 255) $rgb['green'] = mt_rand(0, 255); 

                $rgb['blue'] = $rgb['blue'] + ((mt_rand(0,100) % 2) == 1 ? 1 : -1) * mt_rand(0, 255 - $rgb['blue']); 
                if ($rgb['blue'] < 0 || $rgb['blue'] > 255) $rgb['blue'] = mt_rand(0, 255); 

                 $dotColor = ImageColorAllocate($image, $rgb['red'], $rgb['green'], $rgb['blue']); 
            } 
            ImageSetPixel($image, $x, $y, $dotColor); 
        } 
        
        return $image; 
    } 


    /** 
    * @return String 
    * @desc generate the string 
    */ 
    function generateString() { 
        $string = $this->create_random_value($this -> length, $this -> captchaType); 
        $this -> string = $string; 
        return true; 
    } 


    /** 
    * @return void 
    * @desc send image header 
    */ 
    function sendHeader() { 
        header('Content-type: image/' . $this -> type); 
    } 
    
    /** 
    * @return String 
    * @desc return the string 
    */ 
    function getString() { 
        return $this -> string; 
    } 
    
    
  function create_random_value($length, $type = 'mixed') { 
    if ( ($type != 'mixed') && ($type != 'chars') && ($type != 'digits')) return false; 

    $rand_value = ''; 
    while (strlen($rand_value) < $length) { 
      if ($type == 'digits') { 
        $char = mt_rand(0,9); 
      } else { 
        $char = chr(mt_rand(0,255)); 
      } 
      if ($type == 'mixed') { 
        if (preg_match('/^[a-z0-9]$/i', $char)) $rand_value .= $char; 
      } elseif ($type == 'chars') { 
        if (preg_match('/^[a-z]$/i', $char)) $rand_value .= $char; 
      } elseif ($type == 'digits') { 
        if (preg_match('/^[0-9]$/i', $char)) $rand_value .= $char; 
      } 
    } 

    return $rand_value; 
  } 
}