PHP Classes

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: 5 years 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; } }