功能:
1.按比例縮小/放大
2.填充背景色
3.按區域裁剪
4.添加水印,包括水印的位置,透明度等
使用imagemagick/GD庫實現,imagemagick地址:www.imagemagick.org
需要安裝imagemagick,安裝方法如下:點擊查看
PicThumb.class.php
<?php /** 縮略圖生成類,支持imagemagick及gd庫兩種處理 * Date: 2013-07-15 * Author: fdipzone * Ver: 1.2 * * Func: * public set_config: 設置參數 * public create_thumb: 生成縮略圖 * private fit: 縮略圖片 * private crop: 裁剪圖片 * private gd_fit: GD庫縮略圖片 * private gd_crop: GD庫裁剪圖片 * private get_size: 獲取要轉換的size * private get_crop_offset: 獲取裁圖的偏移量 * private add_watermark: 添加水印 * private check_handler: 判斷處理程序是否已安裝 * private create_dirs: 創建目錄 * private exists: 判斷參數是否存在 * private to_log: 記錄log * private hex2rgb: hex顏色轉rgb顏色 * private get_file_ext: 獲取圖片類型 * * ver: 1.1 增加GD庫處理 * ver: 1.2 增加width,height錯誤參數處理 * 增加當圖片colorspace不為RGB時作轉RGB處理 * 修正使用crop保存為gif時出現透明無效區域問題,使用+repage參數,刪除透明無效區域即可 * * tips:建議使用imagemagick * GD庫不支持透明度水印,如果必須使用透明水印,請將水印圖片做成有透明度。 * GD庫輸出gif如加透明水印,會有問題。 */ class PicThumb{ // class start private $_log = null; // log file private $_handler = null; // 進行圖片處理的程序,imagemagick/gd庫 private $_type = 'fit'; // fit or crop private $_source = null; // 原圖路徑 private $_dest = null; // 縮略圖路徑 private $_watermark = null; // 水印圖片 private $_opacity = 75; // 水印圖片透明度,gd庫不支持 private $_gravity = 'SouthEast'; // 水印擺放位置 NorthWest, North, NorthEast, West, Center, East, SouthWest, South, SouthEast private $_geometry = '+10+10'; // 水印定位,gd庫不支持 private $_croppos = 'TL'; // 截圖的位置 TL TM TR ML MM MR BL BM BR private $_bgcolor = null; // 填充的背景色 private $_quality = 90; // 生成的圖片質量 private $_width = null; // 指定區域寬度 private $_height = null; // 指定區域高度 // 初始化 public function __construct($logfile=''){ if($logfile!=''){ $this->_log = $logfile; } } // 設置參數 public function set_config($param=array()){ $this->_handler = $this->exists($param, 'handler')? strtolower($param['handler']) : null; $this->_type = $this->exists($param, 'type')? strtolower($param['type']) : 'fit'; $this->_watermark = $this->exists($param, 'watermark')? $param['watermark'] : null; $this->_opacity = $this->exists($param, 'opacity')? $param['opacity'] : 75; $this->_gravity = $this->exists($param, 'gravity')? $param['gravity'] : 'SouthEast'; $this->_geometry = $this->exists($param, 'geometry')? $param['geometry'] : '+10+10'; $this->_croppos = $this->exists($param, 'croppos')? $param['croppos'] : 'TL'; $this->_bgcolor = $this->exists($param, 'bgcolor')? $param['bgcolor'] : null; $this->_quality = $this->exists($param, 'quality')? $param['quality'] : 90; $this->_width = $this->exists($param, 'width')? $param['width'] : null; $this->_height = $this->exists($param, 'height')? $param['height'] : null; } /** 創建縮略圖 * @param String $source 原圖 * @param String $dest 目標圖 * @return boolean */ public function create_thumb($source, $dest){ // 檢查使用的handler是否已安裝 if(!$this->check_handler()){ $this->to_log('handler not installed'); return false; } // 判斷區域寬高是否正確 if(!is_numeric($this->_width) || !is_numeric($this->_height) || $this->_width<=0 || $this->_height<=0){ $this->to_log('width or height invalid'); return false; } // 判斷源文件是否存在 if(!file_exists($source)){ $this->to_log($source.' not exists'); return false; } // 創建目標文件路徑 if(!$this->create_dirs($dest)){ $this->to_log(dirname($dest).' create fail'); return false; } $this->_source = $source; // 源文件 $this->_dest = $dest; // 目標文件 // 處理圖片 switch($this->_type){ case 'fit': if($this->_handler=='imagemagick'){ return $this->fit(); }else{ return $this->gd_fit(); } break; case 'crop': if($this->_handler=='imagemagick'){ return $this->crop(); }else{ return $this->gd_crop(); } break; default: $this->to_log($this->_type.' not fit and crop'); return false; } } /** 按比例壓縮或拉伸圖片 * @return boolean */ private function fit(){ // 判斷是否填充背景 $bgcolor = ($this->_bgcolor!=null)? sprintf(" -background '%s' -gravity center -extent '%sx%s' ", $this->_bgcolor, $this->_width, $this->_height) : ""; // 判斷是否要轉為RGB $source_info = getimagesize($this->_source); $colorspace = (!isset($source_info['channels']) || $source_info['channels']!=3)? ' -colorspace RGB ' : ''; // 命令行 $cmd = sprintf("convert -resize '%sx%s' '%s' %s -quality %s %s '%s'", $this->_width, $this->_height, $this->_source, $bgcolor, $this->_quality, $colorspace, $this->_dest); // 記錄執行的命令 $this->to_log($cmd); // 執行命令 exec($cmd); // 添加水印 $this->add_watermark($this->_dest); return is_file($this->_dest)? true : false; } /** 裁剪圖片 * @return boolean */ private function crop(){ // 獲取生成的圖片尺寸 list($pic_w, $pic_h) = $this->get_size(); // 獲取截圖的偏移量 list($offset_w, $offset_h) = $this->get_crop_offset($pic_w, $pic_h); // 判斷是否要轉為RGB $source_info = getimagesize($this->_source); $colorspace = (!isset($source_info['channels']) || $source_info['channels']!=3)? ' -colorspace RGB ' : ''; // 命令行 $cmd = sprintf("convert -resize '%sx%s' '%s' -quality %s %s -crop %sx%s+%s+%s +repage '%s'", $pic_w, $pic_h, $this->_source, $this->_quality, $colorspace, $this->_width, $this->_height, $offset_w, $offset_h, $this->_dest); // 記錄執行的命令 $this->to_log($cmd); // 執行命令 exec($cmd); // 添加水印 $this->add_watermark($this->_dest); return is_file($this->_dest)? true : false; } /** GD庫按比例壓縮或拉伸圖片 * @return boolean */ private function gd_fit(){ // 獲取生成的圖片尺寸 list($pic_w, $pic_h) = $this->get_size(); list($owidth, $oheight, $otype) = getimagesize($this->_source); switch($otype){ case 1: $source_img = imagecreatefromgif($this->_source); break; case 2: $source_img = imagecreatefromjpeg($this->_source); break; case 3: $source_img = imagecreatefrompng($this->_source); break; default: return false; } // 按比例縮略/拉伸圖片 $new_img = imagecreatetruecolor($pic_w, $pic_h); imagecopyresampled($new_img, $source_img, 0, 0, 0, 0, $pic_w, $pic_h, $owidth, $oheight); // 判斷是否填充背景 if($this->_bgcolor!=null){ $bg_img = imagecreatetruecolor($this->_width, $this->_height); $rgb = $this->hex2rgb($this->_bgcolor); $bgcolor =imagecolorallocate($bg_img, $rgb['r'], $rgb['g'], $rgb['b']); imagefill($bg_img, 0, 0, $bgcolor); imagecopy($bg_img, $new_img, (int)(($this->_width-$pic_w)/2), (int)(($this->_height-$pic_h)/2), 0, 0, $pic_w, $pic_h); $new_img = $bg_img; } // 獲取目標圖片的類型 $dest_ext = $this->get_file_ext($this->_dest); // 生成圖片 switch($dest_ext){ case 1: imagegif($new_img, $this->_dest, $this->_quality); break; case 2: imagejpeg($new_img, $this->_dest, $this->_quality); break; case 3: imagepng($new_img, $this->_dest, (int)(($this->_quality-1)/10)); break; } if(isset($source_img)){ imagedestroy($source_img); } if(isset($new_img)){ imagedestroy($new_img); } // 添加水印 $this->add_watermark($this->_dest); return is_file($this->_dest)? true : false; } /** GD庫裁剪圖片 * @return boolean */ private function gd_crop(){ // 獲取生成的圖片尺寸 list($pic_w, $pic_h) = $this->get_size(); // 獲取截圖的偏移量 list($offset_w, $offset_h) = $this->get_crop_offset($pic_w, $pic_h); list($owidth, $oheight, $otype) = getimagesize($this->_source); switch($otype){ case 1: $source_img = imagecreatefromgif($this->_source); break; case 2: $source_img = imagecreatefromjpeg($this->_source); break; case 3: $source_img = imagecreatefrompng($this->_source); break; default: return false; } // 按比例縮略/拉伸圖片 $tmp_img = imagecreatetruecolor($pic_w, $pic_h); imagecopyresampled($tmp_img, $source_img, 0, 0, 0, 0, $pic_w, $pic_h, $owidth, $oheight); // 裁剪圖片 $new_img = imagecreatetruecolor($this->_width, $this->_height); imagecopyresampled($new_img, $tmp_img, 0, 0, $offset_w, $offset_h, $this->_width, $this->_height, $this->_width, $this->_height); // 獲取目標圖片的類型 $dest_ext = $this->get_file_ext($this->_dest); // 生成圖片 switch($dest_ext){ case 1: imagegif($new_img, $this->_dest, $this->_quality); break; case 2: imagejpeg($new_img, $this->_dest, $this->_quality); break; case 3: imagepng($new_img, $this->_dest, (int)(($this->_quality-1)/10)); break; } if(isset($source_img)){ imagedestroy($source_img); } if(isset($tmp_img)){ imagedestroy($tmp_img); } if(isset($new_img)){ imagedestroy($new_img); } // 添加水印 $this->add_watermark($this->_dest); return is_file($this->_dest)? true : false; } /** 獲取目標圖生成的size * @return Array $width, $height */ private function get_size(){ list($owidth, $oheight) = getimagesize($this->_source); $width = (int)($this->_width); $height = (int)($this->_height); switch($this->_type){ case 'fit': $pic_w = $width; $pic_h = (int)($pic_w*$oheight/$owidth); if($pic_h>$height){ $pic_h = $height; $pic_w = (int)($pic_h*$owidth/$oheight); } break; case 'crop': if($owidth>$oheight){ $pic_h = $height; $pic_w = (int)($pic_h*$owidth/$oheight); }else{ $pic_w = $width; $pic_h = (int)($pic_w*$oheight/$owidth); } break; } return array($pic_w, $pic_h); } /** 獲取截圖的偏移量 * @param int $pic_w 圖寬度 * @param int $pic_h 圖高度 * @return Array $offset_w, $offset_h */ private function get_crop_offset($pic_w, $pic_h){ $offset_w = 0; $offset_h = 0; switch(strtoupper($this->_croppos)){ case 'TL': $offset_w = 0; $offset_h = 0; break; case 'TM': $offset_w = (int)(($pic_w-$this->_width)/2); $offset_h = 0; break; case 'TR': $offset_w = (int)($pic_w-$this->_width); $offset_h = 0; break; case 'ML': $offset_w = 0; $offset_h = (int)(($pic_h-$this->_height)/2); break; case 'MM': $offset_w = (int)(($pic_w-$this->_width)/2); $offset_h = (int)(($pic_h-$this->_height)/2); break; case 'MR': $offset_w = (int)($pic_w-$this->_width); $offset_h = (int)(($pic_h-$this->_height)/2); break; case 'BL': $offset_w = 0; $offset_h = (int)($pic_h-$this->_height); break; case 'BM': $offset_w = (int)(($pic_w-$this->_width)/2); $offset_h = (int)($pic_h-$this->_height); break; case 'BR': $offset_w = (int)($pic_w-$this->_width); $offset_h = (int)($pic_h-$this->_height); break; } return array($offset_w, $offset_h); } /** 添加水印 * @param String $dest 圖片路徑 * <a href="/webkf/PHP/">查看本欄目