2010-02-26 67 views
11

我有一個PHP腳本,保存原始圖像,然後調整大小 - 一個縮略圖和一個較大的圖像,以供網頁瀏覽。除了一些圖像的質量很差外,這種方法效果很好。它似乎用非常低的顏色托盤保存。您可以在http://kalpaitch.com/index.php?filter=white看到的結果 - 點擊標題爲「白衣白」的第一個縮略圖php imagecopyresampled質量差

下面是用於圖像重採樣代碼:

function resizeImg($name, $extension, $size1, $size2) { 
if (preg_match('/jpg|jpeg|JPG|JPEG/',$extension)){ 
    $image = imagecreatefromjpeg($name); 
} 
if (preg_match('/gif|GIF/',$extension)){ 
    $image = imagecreatefromgif($name); 
} 

$old_width = imageSX($image); 
$old_height = imageSY($image); 
$old_aspect_ratio = $old_width/$old_height; 

if($size2 == 0){ 
    $new_aspect_ratio = $old_aspect_ratio; 
    if($old_width > $old_height){ 
     $new_width = $size1; 
     $new_height = $new_width/$old_aspect_ratio; 
    } else { 
     $new_height = $size1; 
     $new_width = $new_height * $old_aspect_ratio; 
    } 
} elseif($size2 > 0){ 
    $new_aspect_ratio = $size1/$size2; 
    //for landscape potographs 
    if($old_aspect_ratio >= $new_aspect_ratio) { 
     $x1 = round(($old_width - ($old_width * ($new_aspect_ratio/$old_aspect_ratio)))/2); 
     $old_width = round($old_width * ($new_aspect_ratio/$old_aspect_ratio)); 
     $y1 = 0; 
     $new_width = $size1; 
     $new_height = $size2; 
     //for portrait photographs 
    } else{ 
     $x1 = 0; 
     $y1 = 0; 
     $old_height = round($old_width/$new_aspect_ratio); 
     $new_width = $size1; 
     $new_height = $size2; 
    } 
} 

$new_image = imagecreatetruecolor($new_width, $new_height); 
imagecopyresampled($new_image, $image, 0, 0, $x1, $y1, $new_width, $new_height, $old_width, $old_height); 

return $new_image; 

非常感謝

附:

[從服務器中刪除照片] 這裏是上傳代碼的其餘部分:

// Move the original to the right place 
     $result = @move_uploaded_file($image['tmp_name'], $origlocation); 

     // Resize the image and save the thumbnail 
     $new_image = resizeImg($origlocation, $extension, 500, 0); 

     if (preg_match("/gif/",$extension)){ 
      imagegif($new_image, $normallocation); 
     } else { 
      imagejpeg($new_image, $normallocation); 
     } 

     // Resize the image and save the thumbnail 
     $new_image = resizeImg($origlocation, $extension, 190, 120); 

     if (preg_match("/gif/",$extension)){ 
      imagegif($new_image, $thumblocation); 
     } else { 
      imagejpeg($new_image, $thumblocation); 
     } 
+2

你能展示一個事前後的例子嗎? – 2010-02-27 00:00:10

+0

我不是100%清楚,但它聽起來像你得到的一些圖像是一定的大小,你的腳本實際上調整它大於它最初?如果你這樣做,質量將會很糟糕。 – Jage 2010-02-27 00:02:56

+0

如果只給出一個尺寸,則腳本不會按比例調整圖像大小。如果給出兩種尺寸,它將調整尺寸並裁剪其餘部分而不改變寬高比。 重採樣的圖像總是比原始圖像的分辨率低得多。上面的照片不是原始的,它們都是相同的分辨率,但之前用photoshop保存,而後一個用我的腳本保存。 – kalpaitch 2010-02-27 00:10:31

回答

24

質量損失不是imagecopyresampled(),而是JPEG壓縮。不幸的是,GD的壓縮算法與Photoshop不匹配 - 事實上,很少。但是你可以改善的結果:GD的默認JPG壓縮級別是100

75可以使用第三個參數提高質量imagejpeg()(我假設你正在使用的最終輸出):

imagejpeg ($new_image, null, 99); 

在90-100範圍內玩耍。圖像的文件大小會比原來的大 - 這將是您付出的代價。但應該可以實現可比較的質量。

或者,正如約翰·希梅爾曼在評論中所說的那樣,嘗試使用imagepng()以獲得更好的質量 - 當然,價格也是顯着更大的文件大小。

+4

作爲對任何人都好奇的最後一點。我已經將imagejpeg()質量更改爲99,並且我獲得了更好的圖像。雖然 - 與默認值之間的區別是文件大小增加了1000%(默認值爲12kb,110kb爲高質量壓縮) – kalpaitch 2010-02-27 01:18:01

+1

只是在閱讀完本文後提出的一個建議。使用縮略圖系統,不需要縮略圖圖像與原始全尺寸圖像的格式相同,我的實用功能會被問到「該圖像的縮略圖文件是什麼,它是否已經存在?」所以如果被問及file.jpg,它會返回thumbnail_cache/file.jpg。我改變了這種方式,總是以.png格式縮略圖回覆,所以如果被問及file.jpg,它會返回thumbnail_cache/file.png並生成一個png縮略圖。這避免了對GD jpg壓縮的擔憂。 – Neek 2013-04-04 06:30:54

1

好,php.net文檔說,你應該有一個imagecreatetruecolor()形象,爲您dest_image,如果你想避免使用只有255調色板,但你已經這樣做。

我想一個替代方案是使用外部工具,如imagemagick與system()調用。

+0

是啊不知道PHP是非常有益的。正如你所看到的,我已經使用imagecopyresized完成了第三個測試圖像,它的表現稍好一些,但還不夠。 – kalpaitch 2010-02-27 00:49:07

0
function img_resize($tmpname, $size, $save_dir, $save_name, $maxisheight = 0) 
{ 
    $save_dir .= (substr($save_dir,-1) != "/") ? "/" : ""; 
    $gis = getimagesize($tmpname); 
    $type = $gis[2]; 

    switch($type) 
    { 
     case "1": $imorig = imagecreatefromgif($tmpname); break; 
     case "2": $imorig = imagecreatefromjpeg($tmpname);break; 
     case "3": $imorig = imagecreatefrompng($tmpname); break; 
     default: $imorig = imagecreatefromjpeg($tmpname); 
    } 

    $x = imagesx($imorig); 
    $y = imagesy($imorig); 

    $woh = (!$maxisheight)? $gis[0] : $gis[1] ; 
    if($woh <= $size) 
    { 
     $aw = $x; 
     $ah = $y; 
    } 
    else 
    { 
     if(!$maxisheight) 
     { 
      $aw = $size; 
      $ah = $size * $y/$x; 
     } 
     else 
     { 
      $aw = $size * $x/$y; 
      $ah = $size; 
     } 
    } 
    $im = imagecreatetruecolor($aw,$ah); 

    if (imagecopyresampled($im,$imorig , 0,0,0,0,$aw,$ah,$x,$y)) 

    if (imagejpeg($im, $save_dir.$save_name)) 

     return true; 

    else 

     return false; 

} 
2

快速的髒訣竅是使上imagecopyresized()縮略圖1000×1000個像素(或更多),則設置JPEG質量至20或更少上imagejpeg($img, $savePath, 20);。輸出通常會小於100 kb

讓客戶端CSS進行大小調整,當縮放到縮略圖大小時,圖片將快速加載並在現代瀏覽器中看起來完美無瑕。