<?php /** * 影像處理類 * * @author Carmen <e.carmen.hyc@gmail.com> * * * 生成驗證碼:Image::verify(長度, 寬, 高) * * 加蓋圖片水印:Image::water(圖片路徑, 水印圖路徑, 儲存路徑) * * 加蓋文字水印:Image::text(圖片路徑, 文字內容, 儲存路徑) * * 生成縮圖:Image::thumb(圖片路徑, 寬, 高, 儲存路徑) * * ps:儲存路徑引數均為留空則替換原圖 * * 為了減少引數,部份配置項採用常量定義 * 嵌入框架時,找到每個方法的初始處把常量替換成配置檔案項 * 如 ThinkPHP 可採用 C() 函式代替常量定義 */ /**********縮圖配置項**********/ //縮圖寬度 define('THUMB_WIDTH', 200); //縮圖高度 define('THUMB_HEIGHT', 120); Class Image { /** * 生成驗證碼 * @param [Integer] $length [驗證碼長度] * @param [Integer] $width [驗證碼寬度] * @param [Integer] $height [驗證碼高度] * @return [boolean] */ Static Public function verify ($length = NULL, $width = NULL, $height = NULL) { //環境檢測 if (!self::checkCondition()) return false; //初始化引數(放進框架時把常量換成 讀取配置檔案項 ) $length = empty($length) ? C('VERIFY_LENGTH') : $length; $width = empty($width) ? C('VERIFY_WIDTH') : $width; $height= empty($height) ? C('VERIFY_HEIGHT') : $height; $bgColor = C('VERIFY_BGCOLOR'); $seed = C('VERIFY_SEED'); $fontFile = C('VERIFY_FONTFILE'); $size = C('VERIFY_SIZE'); $fontColor = C('VERIFY_COLOR'); $name = C('VERIFY_NAME'); $fn = C('VERIFY_FUNC'); //建立畫布影像 $verify = imagecreatetruecolor($width, $height); //畫布背景色 $rgb = self::colorTrans($bgColor); $color = imagecolorallocate($verify, $rgb['red'], $rgb['green'], $rgb['blue']); imagefill($verify, 0, 0, $color); //寫入背景干擾字型 $len = strlen($seed) - 1; for ($i = 0; $i < 20; $i++) { $color = imagecolorallocate($verify, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255)); imagestring($verify, 5, mt_rand(0, $width), mt_rand(0, $height), $seed[mt_rand(0, $len)], $color); } $rgb = self::colorTrans($fontColor); $fontColor = imagecolorallocate($verify, $rgb['red'], $rgb['green'], $rgb['blue']); //寫入驗證碼 $code = ''; $left = ($width - $size * $length) / 2; $y = $height - ($height - $size) / 2; for ($i = 0; $i < $length; $i++) { $font = $seed[mt_rand(0, $len)]; $x = $size * $i + $left; imagettftext($verify, $size, mt_rand(-30, 30), $x, $y, $fontColor, $fontFile, $font); $code .= $font; } $_SESSION[$name] = $fn($code); //干擾線 for ($i = 0, $h = $height / 2 - 2; $i < 5; $i++, $h++) { $color = imagecolorallocate($verify, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255)); $cx = mt_rand(-10, $width + 10); $cy = mt_rand(-10, $height + 10); $cw = mt_rand(-10, $width + 10); $ch = mt_rand(-10, $height + 10); imageellipse($verify, $cx, $cy, $cw, $ch, $color); imageellipse($verify, $cx + 1, $cy + 1, $cw + 1, $ch + 1, $color); imageline($verify, 0, $h, $width, $h, $fontColor); } //輸入影像 header('Content-type:image/png'); imagepng($verify); imagedestroy($verify); return true; } /** * 加蓋圖片水印 * @param [String] $img [圖片路徑] * @param [String] $water [水印圖路徑] * @param [String] $save [儲存路徑|留空則替換原圖] * @return [Boolean] */ Static Public function water ($img, $water = '', $save = NULL) { if (!self::checkCondition($img)) return false; //初始化引數(放進框架時把常量換成 讀取配置檔案項 ) $water = empty($water) ? C('WATER_IMAGE') : $water; $pos = C('WATER_POS'); $alpha = C('WATER_ALPHA'); $compression = C('WATER_COMPRESSION'); if (!file_exists($water)) return false; //原圖寬、高與型別 $imgInfo = getimagesize($img); $imgW = $imgInfo[0]; $imgH = $imgInfo[1]; $imgT = self::getImageType($imgInfo[2]); //水印圖寬、高與型別 $waterInfo = getimagesize($water); $waterW = $waterInfo[0]; $waterH = $waterInfo[1]; $waterT = self::getImageType($waterInfo[2]); //水印圖大於原圖時不作處理 if ($imgW < $waterW || $imgH < $waterH) return false; //計算水印位置 $pos = self::getPosition($imgW, $imgH, $waterW, $waterH, $pos); $x = $pos['x']; $y = $pos['y']; //開啟原圖資源 $fn = 'imagecreatefrom' . $imgT; $image = $fn($img); //開啟水印圖資源 $fn = 'imagecreatefrom' . $waterT; $water = $fn($water); //蓋上水印圖 if ($waterT == 'png') { imagecopy($image, $water, $x, $y, 0, 0, $waterW, $waterH); } else { imagecopymerge($image, $water, $x, $y, 0, 0, $waterW, $waterH, $alpha); } //儲存路徑 $save = self::savePath($save, $img); $fn = 'image' . $imgT; if ($imgT == 'jpeg') { $fn($image, $save, $compression); } else { $fn($image, $save); } //釋放資源 imagedestroy($image); imagedestroy($water); return true; } /** * 加蓋文字水印 * @param [String] $img [圖片路徑] * @param [String] $text [文字內容] * @param [String] $save [儲存路徑|留空則替換原圖] * @return [Boolean] */ Static Public function text ($img, $text = '', $save = NULL) { if (!self::checkCondition($img)) return false; //初始化引數(放進框架時把常量換成 讀取配置檔案項 ) $text = empty($text) ? WATER_TEXT : $text; $pos = WATER_POS; $angle = WATER_ANGLE; $fontSize = WATER_FONTSIZE; $fontColor = WATER_FONTCOLOR; $fontFile = WATER_FONTFILE; $charset = WATER_CHARSET; $compression = WATER_COMPRESSION; //文字水印寬、高 $waterInfo = imagettfbbox($fontSize, $angle, $fontFile, $text); $waterW = $waterInfo[2] - $waterInfo[0]; $waterH = $waterInfo[1] - $waterInfo[7]; //原圖寬、高、型別 $imgInfo = getimagesize($img); $imgW = $imgInfo[0]; $imgH = $imgInfo[1]; $type = self::getImageType($imgInfo[2]); //計算水印位置 $pos = self::getPosition($imgW, $imgH, $waterW, $waterH, $pos); $x = $pos['x']; $y = $pos['y'] + $fontSize / 2; //開啟原圖資源 $fn = 'imagecreatefrom' . $type; $image = $fn($img); //寫入水印文字 $rgb = self::colorTrans($fontColor); $color = imagecolorallocate($image, $rgb['red'], $rgb['green'], $rgb['blue']); $text = iconv($charset, 'UTF-8', $text); imagettftext($image, $fontSize, $angle, $x, $y, $color, $fontFile, $text); //儲存路徑 $save = self::savePath($save, $img); $fn = 'image' . $type; if ($type == 'jpeg') { $fn($image, $save, $compression); } else { $fn($image, $save); } //釋放資源 imagedestroy($image); return true; } /** * 生成縮圖(等比例縮放) * @param [String] $img [圖片路徑] * @param [String] $width [縮略寬度] * @param [String] $height [縮略高度] * @param [String] $save [儲存路徑|留空則替換原圖] * @return [Boolean] */ Static Public function thumb ($img, $width = '', $height = '', $save = NULL) { if (!self::checkCondition($img)) return false; //初始化引數(放進框架時把常量換成 讀取配置檔案項 ) $width = empty($width) ? THUMB_WIDTH : $width; $height = empty($height) ? THUMB_HEIGHT : $height; //原圖寬、高、型別 $imgInfo = getimagesize($img); $imgW = $imgInfo[0]; $imgH = $imgInfo[1]; $type = self::getImageType($imgInfo[2]); //縮放比 $ratio = max($width / $imgW, $height / $imgH); //縮圖大於原圖不作處理 if ($ratio >= 1) return false; //等比例縮放後寬、高 $width = floor($imgW * $ratio); $height = floor($imgH * $ratio); //建立縮圖畫布 if ($type == 'gif') { $thumb = imagecreate($width, $height); $color = imagecolorallocate($thumb, 0, 255, 0); } else { $thumb = imagecreatetruecolor($width, $height); //PNG圖片透明處理 if ($type == 'png') { //關閉混色模式 imagealphablending($thumb, false); //儲存透明通道 imagesavealpha($thumb, true); } } //開啟原圖資源 $fn = 'imagecreatefrom' . $type; $image = $fn($img); //原圖移至縮圖畫布並調整大小 if (function_exists('imagecopyresampled')) { imagecopyresampled($thumb, $image, 0, 0, 0, 0, $width, $height, $imgW, $imgH); } else { imagecopyresized($thumb, $image, 0, 0, 0, 0, $width, $height, $imgW, $imgH); } //GIF圖透明處理 if ($type == 'gif') imagecolortransparent($thumb, $color); //儲存路徑 $save = self::savePath($save, $img); $fn = 'image' . $type; $fn($thumb, $save); //釋放資源 imagedestroy($image); imagedestroy($thumb); return true; } /** * 圖片儲存路徑 * @param [String] $save [儲存路徑] * @param [String] $img [原圖路徑] * @return [String] */ Static Private function savePath ($save, $img) { if (!$save) return $img; $pathInfo = pathinfo($img); $path = rtrim($save, '/') . '/'; is_dir($path) || mkdir($path, 0777, true); return $path . time() . mt_rand(1000, 9999) . '.' . $pathInfo['extension']; } /** * 計算水印圖位置 * @param [Integer] $IW [原圖寬] * @param [Integer] $IH [原圖高] * @param [Integer] $WW [水印寬] * @param [Integer] $WH [水印高] * @param [Integer] $pos [九宮格位置] * @return [Array] [x, y] */ Static Private function getPosition ($IW, $IH, $WW, $WH, $pos) { $x = 20; $y = 20; switch ($pos) { case 1 : break; case 2 : $x = ($IW - $WW) / 2; break; case 3 : $x = $IW - $WW - 20; break; case 4 : $y = ($IH - $WH) / 2; break; case 5 : $x = ($IW - $WW) / 2; $y = ($IH - $WH) / 2; break; case 6 : $x = $IW - $WW - 20; $y = ($IH - $WH) / 2; break; case 7 : $y = $IH - $WH - 20; break; case 8 : $x = ($IW - $WW) / 2; $y = $IH - $WH - 20; break; case 9 : $x = $IW - $WW - 20; $y = $IH - $WH - 20; break; default : $x = mt_rand(0, $IW - $WW); $y = mt_rand(0, $IH - $WH); } return array('x' => $x, 'y' => $y); } /** * 圖片型別 * @param [Integer] $typeNum [型別識別號] * @return [String] */ Static Private function getImageType ($typeNum) { switch($typeNum) { case 1 : return 'gif'; case 2 : return 'jpeg'; case 3 : return 'png'; } } /** * 16進位制色值轉換為RGB * @param [Sting] $color [16進位制色值] * @return [Array] [red, green, blue] */ Static Private function colorTrans($color) { $color = ltrim($color, '#'); return array( 'red' => hexdec($color[0] . $color[1]), 'green' => hexdec($color[2] . $color[3]), 'blue' => hexdec($color[4] . $color[5]) ); } /** * 影像處理環境檢測 * @return boolean */ Static Private function checkCondition ($file = NULL) { return is_null($file) ? extension_loaded('GD') && function_exists('imagecreatetruecolor') && function_exists('imagepng') : extension_loaded('GD') && file_exists($file); } } ?>
評論(2)