2014年8月26日 星期二

【PHP】縮圖不失真


最近要做縮圖的工作,試了幾個function,
發現縮圖後的圖都失真的,變得比較模糊,
最後終於找不到不失真的function。
/*  Convert image size. true color*/ 
//$src        來源檔案 
//$dest        目的檔案 
//$maxWidth    縮圖寬度 
//$maxHeight    縮圖高度 
//$quality    JPEG品質 
function ImageCopyResizedTrue($src,$dest,$maxWidth,$maxHeight,$quality=100) { 
  //檢查檔案是否存在 
  if (file_exists($src)  && isset($dest)) { 
      // 目錄是否存在
      $dir = dirname($dest);
      if (!is_dir($dir)){
        mkdir($dir,0777);
      }
      
      $destInfo  = pathinfo($dest); 
      $srcSize   = getimagesize($src); //圖檔大小 
      $srcRatio  = $srcSize[0]/$srcSize[1]; // 計算寬/高 
      $destRatio = $maxWidth/$maxHeight; 
      if ($destRatio > $srcRatio) { 
          $destSize[1] = $maxHeight; 
          $destSize[0] = $maxHeight*$srcRatio; 
      } 
      else { 
          $destSize[0] = $maxWidth; 
          $destSize[1] = $maxWidth/$srcRatio; 
      } 

      //GIF 檔不支援輸出,因此將GIF轉成JPEG 
      if ($destInfo['extension'] == "gif") $dest = substr_replace($dest, 'jpg', -3); 

      //建立一個 True Color 的影像 
      $destImage = imagecreatetruecolor($destSize[0],$destSize[1]); 

      //根據副檔名讀取圖檔 
      switch ($srcSize[2]) { 
          case 1: $srcImage = imageCreateFromGif($src); break; 
          case 2: $srcImage = imageCreateFromJpeg($src); break; 
          case 3: $srcImage = imageCreateFromPng($src); break; 
          default: return false; break; 
      } 

      //取樣縮圖 
      imagecopyresampled($destImage, $srcImage, 0, 0, 0, 0,$destSize[0],$destSize[1], 
                          $srcSize[0],$srcSize[1]); 

      //輸出圖檔 
      switch ($srcSize[2]) { 
          case 1: case 2: imagejpeg($destImage,$dest,$quality); break; 
          case 3: imagepng($destImage,$dest); break; 
      } 
      return true; 
  } 
  else { 
      return false; 
  } 
} 
  
將它寫成Class方便之後使用
此class是可將一個目錄裡所有的圖片縮圖,
並存到另一個目錄,且可設定多個size。
// 使用方法
set_time_limit(0);
$imgPath = $_SERVER['DOCUMENT_ROOT'].'/data/images'; // 原始目錄

$thumb_150 = $_SERVER['DOCUMENT_ROOT'].'/data/images_150'; // 縮圖目錄
$thumb_110 = $_SERVER['DOCUMENT_ROOT'].'/data/images_110';

$igtb = new ImgThumb();
$igtb->oriPath = $imgPath;
$igtb->target = array(
         array($thumb_150,150,150),
         array($thumb_110,110,110), // 縮圖種類及大小
        );
$igtb->startThumb();

      
// @author - wsxrtgvbuikm@gmail.com
class ImgThumb {

 public $oriPath, // 要複製的路徑
     $target = array(
           array('路徑1',150,150) // 可多個 @parameter 路徑,width,height
         ),
     $imgArr;

 public function __construct(){
  $this->imgArr = array('jpg','jpeg','png','gif','bmp');
 }

 public function startThumb(){
  $this->img_thumb($this->oriPath);
  
 }

 public function img_thumb($dir){
  
  $dirArr = scandir($dir);
  foreach($dirArr as $val){
   if ($val == '.' || $val == '..') continue;
   
   $file = $dir.'/'.$val;
   $ext = strtolower(pathinfo($val, PATHINFO_EXTENSION));
   
   if (in_array($ext,$this->imgArr)){ 
    $extend = str_replace($this->oriPath,'',dirname($file));
    foreach($this->target as $arr){
     $target = $arr[0].$extend;
     if (!is_file($target.'/'.basename($file))) // 沒圖縮圖再跑

      $this->ImageCopyResizedTrue($file,$target.'/'.basename($file),$arr[1],$arr[2]);

    }
   }
   
   if (is_dir($file)){ // 是目錄就繼續找
    $this->img_thumb($file);
   }
   
  } // end foreach
  
 }
 
 
 /*  Convert image size. true color*/ 
 //$src        來源檔案 
 //$dest        目的檔案 
 //$maxWidth    縮圖寬度 
 //$maxHeight    縮圖高度 
  //$quality    JPEG品質 
  public function ImageCopyResizedTrue($src,$dest,$maxWidth,$maxHeight,$quality=100) { 
   //檢查檔案是否存在 
   if (file_exists($src)  && isset($dest)) { 
     // 目錄是否存在
     $dir = dirname($dest);
     if (!is_dir($dir)){
      mkdir($dir,0777);
     }
     
     $destInfo  = pathinfo($dest); 
     $srcSize   = getimagesize($src); //圖檔大小 
     $srcRatio  = $srcSize[0]/$srcSize[1]; // 計算寬/高 
     $destRatio = $maxWidth/$maxHeight; 
     if ($destRatio > $srcRatio) { 
       $destSize[1] = $maxHeight; 
       $destSize[0] = $maxHeight*$srcRatio; 
     } 
     else { 
       $destSize[0] = $maxWidth; 
       $destSize[1] = $maxWidth/$srcRatio; 
     } 

     //GIF 檔不支援輸出,因此將GIF轉成JPEG 
     if ($destInfo['extension'] == "gif") $dest = substr_replace($dest, 'jpg', -3); 

     //建立一個 True Color 的影像 
     $destImage = imagecreatetruecolor($destSize[0],$destSize[1]); 

     //根據副檔名讀取圖檔 
     switch ($srcSize[2]) { 
       case 1: $srcImage = imageCreateFromGif($src); break; 
       case 2: $srcImage = imageCreateFromJpeg($src); break; 
       case 3: $srcImage = imageCreateFromPng($src); break; 
       default: return false; break; 
     } 

     //取樣縮圖 
     imagecopyresampled($destImage, $srcImage, 0, 0, 0, 0,$destSize[0],$destSize[1], 
               $srcSize[0],$srcSize[1]); 

     //輸出圖檔 
     switch ($srcSize[2]) { 
       case 1: case 2: imagejpeg($destImage,$dest,$quality); break; 
       case 3: imagepng($destImage,$dest); break; 
     } 
     return true; 
   } 
   else { 
     return false; 
   } 
 } 
}
  

沒有留言:

張貼留言