function vvcode_render_code($code) { if (!empty($code)) { $imwidth = 200; $imheight = 40; $font_size = $imheight * 0.75; $font_position = $imheight * 0.3; Header("Content-type: image/Jpeg"); $im = @ImageCreate($imwidth, $imheight) or die("Cannot Initialize new GD image stream"); $background_color = ImageColorAllocate($im, 255, 255, 255); $text_color = ImageColorAllocate($im, 64, 55, 53); $border_color = ImageColorAllocate($im, 178, 178, 178); $noise_color = ImageColorAllocate($im, 200, 207, 220); /* generate random dots in background */ for ($n = 0; $n < $imwidth * $imheight / 3; $n++) { imagefilledellipse($im, mt_rand(0, $imwidth), mt_rand(0, $imheight), 1, 1, $noise_color); } /* generate random lines in background */ for ($n = 0; $n < $imwidth * $imheight / 150; $n++) { imageline($im, mt_rand(0, $imwidth), mt_rand(0, $imheight), mt_rand(0, $imwidth), mt_rand(0, $imheight), $noise_color); } //strip any spaces that may have crept in //end-user wouldn't know to type the space! :) $code = str_replace(" ", "", $code); $x = 0; $stringlength = strlen($code); for ($i = 0; $i < $stringlength; $i++) { $x = $x + $font_size; $y = $font_position; $font = ImageLoadFont("includes/fonts/automatic.gdf"); $single_char = substr($code, $i, 1); imagechar($im, $font, $x, $y, $single_char, $text_color); } imagerectangle($im, 0, 0, $imwidth - 1, $imheight - 1, $border_color); ImageJpeg($im); ImageDestroy; } }
if ($col_type == 0) { $text_r = rand_color(); $text_g = rand_color(); $text_b = rand_color(); $text_colour2 = ImageColorAllocate($im2, $text_r, $text_g, $text_b); } // write each char in different font for ($i = 0; $i < strlen($word); $i++) { if ($col_type == 1) { $text_r = rand_color(); $text_g = rand_color(); $text_b = rand_color(); $text_colour2 = ImageColorAllocate($im2, $text_r, $text_g, $text_b); } $j = $rand_func(0, sizeof($font_locations) - 1); $font = ImageLoadFont($font_locations[$j]); ImageString($im2, $font, $word_start_x + $font_widths[$j] * $i, $word_start_y, $word[$i], $text_colour2); } // use last pixelwidth $font_pixelwidth = $font_widths[$j]; // for debug: //sendImage($im2); ////////////////////////////////////////////////////// ////// Morph Image: ////////////////////////////////////////////////////// // calculate how big the text is in pixels // (so we only morph what we need to) $word_pix_size = $word_start_x + strlen($word) * $font_pixelwidth; $y_pos = 0; // firstly move each character up or down a bit: for ($i = $word_start_x; $i < $word_pix_size; $i += $font_pixelwidth) {
function drawtext($image, $text, $size, $font, $color, $offsetx, $offsety, $shadow) { global $black; $color = imagecolorallocate($image, $color['r'], $color['g'], $color['b']); if (SERVER_HAS_FREETYPE) { $bbox = imagettfbbox($size, 0, $font, $text); $height = abs($bbox[1]) + abs($bbox[5]); $width = abs($bbox[4]) + abs($bbox[0]); $x = $offsetx + abs($bbox[0]); $y = $offsety + abs($bbox[5]); if ($shadow) { imagettftext($image, $size, 0, $x + 1, $y + 1, $black, $font, $text); } imagettftext($image, $size, 0, $x, $y, $color, $font, $text); } else { $hfont = ImageLoadFont($font); $width = ImageFontWidth($hfont) * strlen($text); $height = ImageFontHeight($hfont); if ($shadow) { imagestring($image, $hfont, $offsetx + 1, $offsety + 1, $text, $black); } imagestring($image, $hfont, $offsetx, $offsety, $text, $color); } return array('HEIGHT' => $height, 'WIDTH' => $width); }
function OutputCAPTCHA() { @session_start(); // 隨機生成明碼、暗碼 $byteTable = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'); // 明碼定義陣列 $LCode = ''; // 明碼 for ($i = 0; $i < $this->CAPTCHA_LENGTH; $i++) { $LCode .= $byteTable[rand(0, count($byteTable) - 1)]; } // 隨機抽碼 $DCode = md5($LCode); // 暗碼 (明碼的MD5) $_SESSION['captcha_dcode'] = $DCode; // 暗碼存入 Session // 生成暫存圖像 $captcha = ImageCreateTrueColor($this->CAPTCHA_WIDTH, $this->CAPTCHA_HEIGHT); $randcolR = rand(100, 230); $randcolG = rand(100, 230); $randcolB = rand(100, 230); // 隨機色碼值 $backColor = ImageColorAllocate($captcha, $randcolR, $randcolG, $randcolB); // 背景色 ImageFill($captcha, 0, 0, $backColor); // 填入背景色 $txtColor = ImageColorAllocate($captcha, $randcolR - 40, $randcolG - 40, $randcolB - 40); // 文字色 $rndFontCount = count($this->CAPTCHA_FONTFACE); // 隨機字型數目 // 打入文字 for ($p = 0; $p < $this->CAPTCHA_LENGTH; $p++) { if ($this->CAPTCHA_FONTMETHOD) { // TrueType 字型 // 設定旋轉角度 (左旋或右旋) if (rand(1, 2) == 1) { $degree = rand(0, 25); } else { $degree = rand(335, 360); } // 圖層, 字型大小, 旋轉角度, X軸, Y軸 (字左下方起算), 字色, 字型, 印出文字 ImageTTFText($captcha, rand(14, 16), $degree, ($p + 1) * $this->CAPTCHA_GAP, $this->CAPTCHA_TEXTY, $txtColor, $this->CAPTCHA_FONTFACE[rand(0, $rndFontCount - 1)], substr($LCode, $p, 1)); } else { // GDF 字型 $font = ImageLoadFont($this->CAPTCHA_FONTFACE[rand(0, $rndFontCount - 1)]); // 圖層, 字型, X軸, Y軸 (字左上方起算), 印出文字, 字色 ImageString($captcha, $font, ($p + 1) * $this->CAPTCHA_GAP, $this->CAPTCHA_TEXTY - 18, substr($LCode, $p, 1), $txtColor); } } // 混淆用 (畫橢圓) for ($n = 0; $n < $this->CAPTCHA_ECOUNT; $n++) { ImageEllipse($captcha, rand(1, $this->CAPTCHA_WIDTH), rand(1, $this->CAPTCHA_HEIGHT), rand(50, 100), rand(12, 25), $txtColor); ImageEllipse($captcha, rand(1, $this->CAPTCHA_WIDTH), rand(1, $this->CAPTCHA_HEIGHT), rand(50, 100), rand(12, 25), $backColor); } // 輸出圖像 header('Content-Type: image/png'); header('Cache-Control: no-cache'); ImagePNG($captcha); ImageDestroy($captcha); }
ImageCopy($temp_bg, $im3, 0, 0, 0, 0, $width, $height); $morph_x = 0; for ($y = 0; $y <= $height; $y += $morph_chunk) { $morph_chunk = mt_rand(1, 5); $morph_x += mt_rand(-1, 1); ImageCopy($im3, $temp_bg, $morph_x, $y, 0, $y, $width, $morph_chunk); } ImageDestroy($temp_bg); myImageBlur($im3); ////////////////////////////////////////////////////// ////// Write Word ////////////////////////////////////////////////////// $word_start_x = mt_rand(5, 32); $word_start_y = 15; // write each char in different color $font = ImageLoadFont($font_locations); $font_width = open_font($font_locations); for ($i = 0; $i < strlen($word); $i++) { $text_r = rand_color(); $text_g = rand_color(); $text_b = rand_color(); $text_colour2 = ImageColorAllocate($im2, $text_r, $text_g, $text_b); ImageString($im2, $font, $word_start_x + $font_width * $i, $word_start_y, $word[$i], $text_colour2); } $font_pixelwidth = $font_width; ////////////////////////////////////////////////////// ////// Morph Image: ////////////////////////////////////////////////////// $word_pix_size = $word_start_x + strlen($word) * $font_pixelwidth; // firstly move each character up or down a bit: $y_pos = 0;
} $angle = 0; //has freetype if (SERVER_HAS_FREETYPE) { $titlefont = "fonts/{$titlefont}.ttf"; $bbox = imagettfbbox($titlefontsize, $angle, $titlefont, $mytitle); $width = abs($bbox[4]) + abs($bbox[0]); $height = abs($bbox[1]) + abs($bbox[5]); $x = abs($bbox[0]); $y = abs($bbox[5]); $image = imagecreatetruecolor($width, $height); $color = imagecolorallocate($image, $titlefontR, $titlefontG, $titlefontB); $white = imagecolorallocate($image, 255, 255, 255); imagefilledrectangle($image, 0, 0, $width - 1, $height - 1, $white); imagettftext($image, $titlefontsize, $angle, $x, $y, $color, $titlefont, $mytitle); } else { $titlefont = "fontsold/{$titlefont}.gdf"; $titlefont = ImageLoadFont($titlefont); $width = ImageFontWidth($titlefont) * strlen($mytitle); $height = ImageFontHeight($titlefont); $image = imagecreatetruecolor($width, $height); $color = imagecolorallocate($image, $titlefontR, $titlefontG, $titlefontB); $white = imagecolorallocate($image, 255, 255, 255); imagefilledrectangle($image, 0, 0, $width - 1, $height - 1, $white); ImageString($image, $titlefont, 0, 0, $mytitle, $color); } header("Content-Type: image/png"); imagepng($image); ImageDestroy($image); ?>
/** * Write word on image * * @param int $width: width of the image in pixels * @param int $height: width of the image in pixels * @param string $word: the captcha word * @param int $textColorType (see constants) * @param array $textPosition: 'horizontal' => horizontal starting position of text, 'vertical' => vertical starting position of text * @param int $colorMaximum: 'darkness' => maximum color darkness along any dimension, 'lightness' => maximum color lightness along any dimension * @param string $backgroundType (see constants) * @param array $fontLocations: array of font files locations * @param array $fontWidths: array of font widths * @param int $morphfactor: text morphing factor * @return string GD image identifier of noisy background */ public static function writeWordOnImage($width, $height, $word, $textColorType, $textPosition, $colorMaximum, $backgroundType, $fontLocations, $fontWidths, $morphFactor = 1) { $image = ImageCreate($width, $height); $image2 = ImageCreate($width, $height); // Set background colour (can change to any colour not in possible $text_col range) // it doesn't matter as it'll be transparent or coloured over. // if you're using background type 'Morphed image blocks', you might want to try to ensure that the color chosen // below doesn't appear too much in any of your background images. $background = ImageColorAllocate($image, 254, 254, 254); $background2 = ImageColorAllocate($image2, 254, 254, 254); // Set transparencies ImageColorTransparent($image, $background); // $image2 transparent to allow characters to overlap slightly while morphing ImageColorTransparent($image2, $background2); // Fill backgrounds ImageFill($image, 0, 0, $background); ImageFill($image2, 0, 0, $background2); // Write word in random starting X position $word_start_x = RandomContentUtility::getRandomNumberInRange(5, $textPosition['horizontal']); // Y positions jiggled about later $word_start_y = $textPosition['vertical']; // Get uniform color if ($textColorType == self::TEXT_COLOR_UNIFORM) { $textColor = RandomContentUtility::getRandomColor($colorMaximum['darkness'], $colorMaximum['lightness'], $backgroundType == self::BACKGROUND_TYPE_MORPHED_IMAGE_BLOCKS); $textColor2 = ImageColorAllocate($image2, $textColor[0], $textColor[1], $textColor[2]); } // Write each character in different font $textFontWidths = array(); $x_pos = $word_start_x; for ($i = 0; $i < strlen($word); $i++) { // Get changing color if ($textColorType == self::TEXT_COLOR_ONE_PER_CHARACTER) { $textColor = RandomContentUtility::getRandomColor($colorMaximum['darkness'], $colorMaximum['lightness'], $backgroundType == self::BACKGROUND_TYPE_MORPHED_IMAGE_BLOCKS); $textColor2 = ImageColorAllocate($image2, $textColor[0], $textColor[1], $textColor[2]); } $fontIndex = RandomContentUtility::getRandomNumberInRange(0, sizeof($fontLocations) - 1); $font = ImageLoadFont($fontLocations[$fontIndex]); ImageString($image2, $font, $x_pos, $word_start_y, $word[$i], $textColor2); $textFontWidths[$i] = $fontWidths[$fontIndex]; $x_pos += $textFontWidths[$i]; } // Morph Image // Firstly move each character up or down a bit: $x_pos = $word_start_x; $y_pos = 0; for ($i = 0; $i < strlen($word); $i++) { // Move on Y axis // Deviate at least 4 pixels between each letter $prev_y = $y_pos; do { $y_pos = RandomContentUtility::getRandomNumberInRange(-5, 5); } while ($y_pos < $prev_y + 2 && $y_pos > $prev_y - 2); ImageCopy($image, $image2, $x_pos, $y_pos, $x_pos, 0, $textFontWidths[$i], $height); $x_pos += $textFontWidths[$i]; } ImageFilledRectangle($image2, 0, 0, $width, $height, $background2); // Randomly morph each character individually on x-axis // This is where the main distortion happens $y_chunk = 1; $morph_x = 0; $orig_x = $word_start_x - $textFontWidths[0]; for ($j = 0; $j < strlen($word); $j++) { $orig_x += $textFontWidths[$j]; $y_pos = 0; for ($i = 0; $i <= $height; $i += $y_chunk) { // morph x += so that instead of deviating from orig x each time, we deviate from where we last deviated to // get it? instead of a zig zag, we get more of a sine wave. // I wish we could deviate more but it looks crap if we do. $morph_x += RandomContentUtility::getRandomNumberInRange(-$morphFactor, $morphFactor); // had to change this to ImageCopyMerge when starting using ImageCreateTrueColor // according to the manual; "when (pct is) 100 this function behaves identically to imagecopy()" // but this is NOT true when dealing with transparencies... ImageCopyMerge($image2, $image, $orig_x + $morph_x, $i + $y_pos, $orig_x, $i, $textFontWidths[$j], $y_chunk, 100); } } ImageFilledRectangle($image, 0, 0, $width, $height, $background); // Now do the same on the y-axis // (much easier because we can just do it across the whole image, don't have to do it char-by-char) $y_pos = 0; $x_chunk = 1; for ($i = 0; $i <= $width; $i += $x_chunk) { // Can result in image going too far off on Y-axis; // not much I can do about that, apart from make image bigger // again, I wish I could do 1.5 pixels $y_pos += RandomContentUtility::getRandomNumberInRange(-1, 1); ImageCopy($image, $image2, $i, $y_pos, $i, 0, $x_chunk, $height); } // Cleanup ImageDestroy($image2); return $image; }