圖片驗證碼類
阿新 • • 發佈:2018-12-15
<?php class base_vcode_gd { //圖片資源 private $image=null; //生成的驗證碼字的個數 public $codeNum; //驗證碼高度 public $height = 35; //驗證碼寬度 public $width = 100; //干擾元素數量 private $disturbColorNum; //生成的code public $code=''; //是否生成中文驗證碼 public function setPicSize($height=35, $width=100) { $this->height = $height; $this->width = $width; } public function length($length) { //設定干擾元素數量 $number=floor($this->width*$this->height/20); if($number > 240-$this->codeNum) { $this->disturbColorNum= 240-$this->codeNum; } else { $this->disturbColorNum=$number; } $this->codeNum = $length; //生成code $this->createCode(); } //顯示驗證碼圖片 public function display() { if( is_file(app::get('base')->res_dir.'/fonts/Menlo.ttc') ) { $fontFace = app::get('base')->res_dir.'/fonts/Menlo.ttc'; } //建立圖片資源 $this->createImage(); //設定干擾顏色 //$this->setDisturbColor(); //往圖片上新增文字 $this->outputText($fontFace); $this->distortionText(); //輸出影象 $this->ouputImage(); } function base64Image() { if( is_file(app::get('base')->res_dir.'/fonts/Menlo.ttc') ) { $fontFace = app::get('base')->res_dir.'/fonts/Menlo.ttc'; } //建立圖片資源 $this->createImage(); //設定干擾顏色 //$this->setDisturbColor(); //往圖片上新增文字 $this->outputText($fontFace); $this->distortionText(); ob_get_clean(); ob_start(); if(imagetypes() & IMG_GIF) { $type = 'gif'; imagepng($this->image); } else if(imagetypes() & IMG_JPG) { $type = 'jpg'; imagepng($this->image); } else if(imagetypes() & IMG_PNG) { $type = 'png'; imagepng($this->image); } else { $type = 'png'; imagepng($this->image); } $imageData = ob_get_contents(); ob_end_clean(); $base64 = 'data:image/' . $type . ';base64,' . base64_encode($imageData); return $base64; } public function get_code() { return strtolower($this->code); } //建立圖片 無邊框 private function createImage() { //生成圖片資源 $this->image=imagecreatetruecolor($this->width,$this->height); //畫出圖片背景 $this->backColor=imagecolorallocate($this->image,mt_rand(255,255),mt_rand(255,255),mt_rand(255,255)); imagefill($this->image,0,0,$this->backColor); } //設定干擾顏色 private function setDisturbColor() { //畫出點干擾 for($i=0;$i<=$this->disturbColorNum;$i++) { $pixelColor=imagecolorallocate($this->image,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255)); imagesetpixel($this->image,mt_rand(0,$this->width),mt_rand(0,$this->height),$pixelColor); } //畫出干擾線 //$this->__wirteSinLine(); } //@扭曲文字 public function distortionText() { $this->distortionImage = imagecreatetruecolor($this->width, $this->height); imagefill($this->distortionImage, 0, 0, $this->backColor); for ($x = 0; $x < $this->width; $x++) { for ($y = 0; $y < $this->height; $y++) { $rgbColor = imagecolorat($this->image, $x, $y); imagesetpixel($this->distortionImage, (int) ($x + sin($y / $this->height * 2 * M_PI - M_PI * 0.5) * 3), $y, $rgbColor); } } $this->image = $this->distortionImage; } //往圖片上新增文字 private function outputText($fontFace='') { //畫出code for($i=0;$i<$this->codeNum;$i++) { $fontColor=imagecolorallocate($this->image,0,0,255); //設定了fontFace 則使用imagettftext if($fontFace) { $fontSize=mt_rand($this->width/$this->codeNum-5,$this->width/$this->codeNum-4); $x=floor(($this->width-3)/$this->codeNum)*$i+5; $y=mt_rand($fontSize, $this->height-5); imagettftext($this->image,$fontSize,mt_rand(-30, 30),$x,$y ,$fontColor, $fontFace,self::msubstr($this->code,$i)); } else { //沒有設定 fontFace 則使用 imagechar $fontSize=mt_rand(4,6); $x=floor($this->width/$this->codeNum)*$i+3; $y=mt_rand(0,$this->height-20); imagechar($this->image,$fontSize,$x,$y,$this->code{$i},$fontColor); } } } //生成code private function createCode() { if( base_mobiledetect::isMobile() && $_COOKIE['browse'] != 'pc') { $string = '0123456789'; } else { $string='0123456789abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; } $code=''; for($i=0;$i<$this->codeNum;$i++) { $char=self::msubstr($string,mt_rand(0,mb_strlen($string,'utf-8')-1)); $this->code.=$char; } } //輸出影象 private function ouputImage() { ob_get_clean(); if(imagetypes() & IMG_GIF) { header("Content-Type:image/gif"); imagepng($this->image); } else if(imagetypes() & IMG_JPG) { header("Content-Type:image/jpeg"); imagepng($this->image); } else if(imagetypes() & IMG_PNG) { header("Content-Type:image/png"); imagepng($this->image); } else { header("Content-Type:image/vnd.wap.wbmp"); imagepng($this->image); } //exit; } //畫正弦干擾線 private function __wirteSinLine($w=100) { $color = imagecolorallocate($this->image,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255)); $img=$this->image; $h=$this->height; $h1=rand(-5,5); $h2=rand(-1,1); $w2=rand(10,15); $h3=rand(4,6); $funArr = array('sin','cos'); $funKey = rand(0,1); $fun = $funArr[$funKey]; for($i=-$w/2;$i<$w/2;$i=$i+0.1) { $y=$h/$h3*$fun($i/$w2)+$h/2+$h1; imagesetpixel($img,$i+$w/2,$y,$color); $h2!=0?imagesetpixel($img,$i+$w/2,$y+$h2,$color):null; } } /* * msubstr() 擷取字串 * */ static private function msubstr($str, $start=0, $length=1, $charset="utf-8") { if(function_exists("mb_substr")) { $slice = mb_substr($str, $start, $length, $charset); } elseif(function_exists('iconv_substr')) { $slice = iconv_substr($str,$start,$length,$charset); } else { $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/"; $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/"; $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/"; $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/"; preg_match_all($re[$charset], $str, $match); $slice = join("",array_slice($match[0], $start, $length)); } return $slice; } // 摧毀資源 public function __destruct() { imagedestroy($this->image); } }