2013-01-10 72 views
1

我有一個創建的函數,它根據參數以不同的方式處理圖像。我在函數中有一些註釋來解釋一下。使用php將jpg保存爲透明png

當我拍攝一張jpg圖像並將其保存爲png格式時,一切都有例外。我剛剛檢查過,即使我使用imagepng(),但將它與擴展名.jpg一起保存,圖像將在正確調整大小的情況下顯示,但帶有.jpg擴展名。但是,如果我上傳相同的.jpg圖像,請使用imagepng()並使用.png擴展名保存它,然後在調整大小後以png格式獲得預期寬度和高度的圖像,並帶有.png擴展名。雖然整個圖像是100%透明的,但左上角有一個1像素×1像素的黑色像素。

我會很感激,如果任何人都可以看看這個,看看他們是否看到我失蹤的東西。我相信1px X 1px來自我用於imagefill()的點,但我不明白爲什麼;它應該像其餘的圖像一樣填充全部透明。

這裏是我的功能:

if(!function_exists("upload")){ 
    //$image = $image file name 
    //$width = intended width of resized image, if 0 it will proportion to height, overrides proportion 
    //$height = intended width of resized image, if 0 it will proportion to width, overrides proportion 
    //$proportion = 2,1,0; 
    //------ 2 = Preserve proportions while adding a border to fill width and height 
    //------ 1 = retain proportion to fit within both given width and height 
    //------ 0 = disregard proportions and resize to the exact width and height 
    function upload($image, $width, $height, $proportion){ 
     // IS GD HERE? 

     $gdv = get_gd_info(); 

     if (!$gdv){ 
      return FALSE; 
     } 

     // GET AN IMAGE THING 

     $ext = trim(strtolower(end(explode('.', $image)))); 

     list($imageX, $imageY, $type) = getimagesize($image); //gets information about new server image 

     // GET THE LESSER OF THE RATIO OF THUMBNAIL H OR W DIMENSIONS 
     $ratio_w = ($width/$imageX); 
     $ratio_h = ($height/$imageY); 
     $ratio = ($ratio_w < $ratio_h) ? $ratio_w : $ratio_h;  

     if($width == 0){ 

      if($imageY > $height){ 
       $newHeight = $height; 
       $newWidth = ($height/$imageY) * $imageX;  
      }else{ 
       $newHeight = $imageY; 
       $newWidth = $imageX;  
      } 

      $width = $newWidth; 
      $height = $newHeight; 

      // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS 
      $fromMidX = 0; 
      $fromMidY = 0; 

     }elseif($height == 0){ 

      if ($imageX > $width){ 
       $newWidth = $width; 
       $newHeight = ($width/$imageX) * $imageY; 
      }else{ 
       $newHeight = $imageY; 
       $newWidth = $imageX;  
      } 

      $width = $newWidth; 
      $height = $newHeight; 

      // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS 
      $fromMidX = 0; 
      $fromMidY = 0; 

     }elseif($proportion == 2){ 

      // COMPUTE THUMBNAIL IMAGE DIMENSIONS 
      $newWidth = $imageX * $ratio; 
      $newHeight = $imageY * $ratio; 

      // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS 
      $fromMidX = ($width - $newWidth)/2.0; 
      $fromMidY = ($height - $newHeight)/2.0; 

     }elseif($proportion == 1){ 

      if ($imageX > $width){ 
       $newHeight = ($width/$imageX) * $imageY; 
       $newWidth = $width; 
      } 
      if ($imageY > $height){ 
       $newHeight = $height; 
       $newWidth = ($height/$imageY) * $imageX; 
      } 

      $fromMidY = 0; 
      $fromMidX = 0; 

     }elseif($proportion == 0){ 

      $newWidth = $width; 
      $newHeight = $height; 

      $fromMidY = 0; 
      $fromMidX = 0;   
     } 

     switch(strtoupper($ext)) 
     { 
      case 'JPG' : 
      case 'JPEG' : 
       $source = imagecreatefromjpeg($image); 
       break; 

      case 'PNG' : 
       $source = imagecreatefrompng($image); 

       break; 

      default : die("UNKNOWN IMAGE TYPE: $image"); 
     } 

     // WHICH FUNCTIONS CAN RESIZE/RESAMPLE THE IMAGE? 
     if ($gdv >= 2) 
     { 

      // IF GD IS AT LEVEL 2 OR ABOVE 
      $target = imagecreatetruecolor($width, $height); 
      $color = imagecolorallocatealpha($target, 0, 0, 0, 127); 

      imagefill($target, 0, 0, $color); 

      imagesavealpha($target, TRUE); 


      imagecopyresampled ($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY); 

     } 
     else 
     { 
      // IF GD IS AT A LOWER REVISION LEVEL 
      $target = imagecreate($width, $height); 
      imagesavealpha($target, TRUE); 
       $empty = imagecolorallocatealpha($thumb,0x00,0x00,0x00,127); 
       imagefill($target, 0, 0, $empty); 
      imagecopyresized($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY); 
     } 

     // SHARPEN THE PIC 
     $sharpenMatrix = array 
     (array(-1.2, -1, -1.2) 
     , array(-1, 20, -1) 
     , array(-1.2, -1, -1.2) 
     ) 
     ; 
     $divisor = array_sum(array_map('array_sum', $sharpenMatrix)); 
     $offset = 0; 
     imageconvolution($target, $sharpenMatrix, $divisor, $offset); 

     if(imagepng($target, $image,9)){ 

      imagedestroy($target); 
     }else{ 

     } 

     return $image; 
    } 
} 

編輯1:我想我應該指出的是,我上傳JPG格式圖像(例如:100像素X 200像素),以及將它們轉換爲png格式(例如:400像素X 200px),但我保留圖像的比例以完美地適合目標.png的中心。所以我會有一個400px X 200px的.png,中間是我的圖片,左邊和右邊是100px,應該是透明的。這種方式很好地適用於沒有純色作爲填充的滑塊。所以我的函數的一個例子是upload($image, 400, 200, 2)

+0

澄清一點不錯hex2rgb/rgb2hex職能想到:如果你上傳JPEG,並將其轉換成PNG,那麼你應該沒有透明像素。但是,您說整個圖像都是透明的,即左上角的像素。我錯過了什麼? – halfer

+0

看看[這裏](http://stackoverflow.com/questions/7610128/use-php-to-convert-jpegs-to-transparent-png) –

+0

@halfer我編輯我的問題,試圖澄清爲什麼我應該有透明像素。我想我應該從一開始就補充說。 –

回答

0

我想出了問題所在。決定我應該使用imagecreatefromjpeg還是imagecreatefrompng的代碼部分不正確地離開傳遞圖像的擴展名而不是其MIME類型。我把它切換到這一點:

switch($type) 
     { 
      case '2' : 
       $source = imagecreatefromjpeg($image); 
       break; 
      case '3' : 
       $source = imagecreatefrompng($image); 
       break; 
      default : die("UNKNOWN IMAGE TYPE: $image"); 
     } 

其中$type從行來,我在那裏

list($imageX, $imageY, $type) = getimagesize($image); 

所以結合在一起的功能是:

if(!function_exists("upload")){ 
    //$image = $image file name 
    //$width = intended width of resized image, if 0 it will proportion to height, overrides proportion 
    //$height = intended width of resized image, if 0 it will proportion to width, overrides proportion 
    //$proportion = 2,1,0; 
    //------ 2 = Preserve proportions while adding a border to fill width and height 
    //------ 1 = retain proportion to fit within both given width and height 
    //------ 0 = disregard proportions and resize to the exact width and height 


    function upload($image, $width, $height, $proportion){ 
     // IS GD HERE? 

     $gdv = get_gd_info(); 

     if (!$gdv){ 
      return FALSE; 
     } 

     // GET AN IMAGE THING 

     $ext = trim(strtolower(end(explode('.', $image)))); 

     list($imageX, $imageY, $type) = getimagesize($image); //gets information about new server image 

     // GET THE LESSER OF THE RATIO OF THUMBNAIL H OR W DIMENSIONS 
     $ratio_w = ($width/$imageX); 
     $ratio_h = ($height/$imageY); 
     $ratio = ($ratio_w < $ratio_h) ? $ratio_w : $ratio_h;  

     if($width == 0){ 

      if($imageY > $height){ 
       $newHeight = $height; 
       $newWidth = ($height/$imageY) * $imageX;  
      }else{ 
       $newHeight = $imageY; 
       $newWidth = $imageX;  
      } 

      $width = $newWidth; 
      $height = $newHeight; 

      // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS 
      $fromMidX = 0; 
      $fromMidY = 0; 

     }elseif($height == 0){ 

      if ($imageX > $width){ 
       $newWidth = $width; 
       $newHeight = ($width/$imageX) * $imageY; 
      }else{ 
       $newHeight = $imageY; 
       $newWidth = $imageX;  
      } 

      $width = $newWidth; 
      $height = $newHeight; 

      // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS 
      $fromMidX = 0; 
      $fromMidY = 0; 

     }elseif($proportion == 2){ 

      // COMPUTE THUMBNAIL IMAGE DIMENSIONS 
      $newWidth = $imageX * $ratio; 
      $newHeight = $imageY * $ratio; 

      // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS 
      $fromMidX = ($width - $newWidth)/2.0; 
      $fromMidY = ($height - $newHeight)/2.0; 

     }elseif($proportion == 1){ 

      if ($imageX > $width){ 
       $newHeight = ($width/$imageX) * $imageY; 
       $newWidth = $width; 
      } 
      if ($imageY > $height){ 
       $newHeight = $height; 
       $newWidth = ($height/$imageY) * $imageX; 
      } 

      $fromMidY = 0; 
      $fromMidX = 0; 

     }elseif($proportion == 0){ 

      $newWidth = $width; 
      $newHeight = $height; 

      $fromMidY = 0; 
      $fromMidX = 0;   
     } 

     switch($type) 
     { 
      case '2' : 
       $source = imagecreatefromjpeg($image); 
       break; 
      case '3' : 
       $source = imagecreatefrompng($image); 
       break; 
      default : die("UNKNOWN IMAGE TYPE: $image"); 
     } 

     // WHICH FUNCTIONS CAN RESIZE/RESAMPLE THE IMAGE? 
     if ($gdv >= 2) 
     { 

      // IF GD IS AT LEVEL 2 OR ABOVE 
      $target = imagecreatetruecolor($width, $height); 
      $color = imagecolorallocatealpha($target, 0, 0, 0, 127); 
      imagefill($target, 0, 0, $color); 
      imagesavealpha($target, TRUE); 
      imagecopyresampled ($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY); 

     } 
     else 
     { 
      // IF GD IS AT A LOWER REVISION LEVEL 
      $target = imagecreate($width, $height); 
      imagesavealpha($target, TRUE); 
       $empty = imagecolorallocatealpha($thumb,0x00,0x00,0x00,127); 
       imagefill($target, 0, 0, $empty); 
      imagecopyresized($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY); 
     } 

     // SHARPEN THE PIC 
     $sharpenMatrix = array 
     (array(-1.2, -1, -1.2) 
     , array(-1, 20, -1) 
     , array(-1.2, -1, -1.2) 
     ) 
     ; 
     $divisor = array_sum(array_map('array_sum', $sharpenMatrix)); 
     $offset = 0; 
     imageconvolution($target, $sharpenMatrix, $divisor, $offset); 

     if(imagepng($target, $image,9)){ 
      imagedestroy($target); 
     } 
     return $image; 
    } 
} 

和實例調用將是:upload("path/to/image/on/server.png", 400, 200, 2) 圖像路徑可以是JPG或PNG MIME類型。但擴展名必須是.png。我想我可以讓它更聰明,你可以有任何擴展名,但是使用這個函數的當前代碼對我來說更有意義。我想最終添加選項來打開或關閉透明度,而是在需要時使用純色(如黑色)。隨意使用和修改。

有,我打算使用這個here