2010-02-26 19 views
11

Orijinal görüntüyü kaydeden bir php betiğim var, ardından yeniden boyutlandırıyorum - web görüntülemesi için bir küçük resim ve daha büyük bir resim. Bu bazı görüntüler ile iyi çalışır, kalitesi korkunç. Çok düşük bir renk paletiyle kaydedilmiş gibi görünüyor. Sen http://kalpaitch.com/index.php?filter=white de sonucu görebilirsiniz - başlık 'beyaz beyaz' ile ilk küçük resme tıklayın Aşağıda php görüntükopi kalitesi düşük kalitede görüntüleniyor

görüntü yeniden örnekleme için kullanılan kod:

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; 

Çok teşekkürler

Not;

[Fotoğraf sunucu kaldırıldı] Ve burada yükleme kodunun gerisi: iyi

// 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

Önce bir örnek gösterebilir misiniz? –

+0

% 100 açık değilim, ancak aldığınız görüntülerin bir kısmı belli bir boyuta benziyor ve senaryonuz aslında orijinalinden daha fazla BÜYÜK olarak yeniden boyutlandırılıyor mu? Bunu yaparsanız kalite çok kötü olur. – Jage

+0

Hayır, yalnızca bir boyut verilirse betik resmi orantılı olarak yeniden boyutlandıramaz. İki boyut verilirse, yeniden boyutlandırılır ve en-boy oranını değiştirmeden kalan kısmı kırpın. Yeniden örneklenen görüntüler, orijinal görüntüden her zaman çok daha düşük çözünürlüktedir. Yukarıdaki fotoğrafın orijinali değil, ikisi de aynı çözünürlüktedir, ancak önce photoshop ile kaydedilir ve sonra script'imle kaydedilir. – kalpaitch

cevap

24

Kalite kaybı, imagecopyresampled()'a değil, JPEG sıkıştırmasına bağlıdır. Ne yazık ki GD'nin sıkıştırma algoritmaları Photoshop'unkilerle uyuşmuyor - aslında çok azı var. Ama sonuç iyileştirebilir:

imagejpeg ($new_image, null, 99); 
: GD'nin varsayılan JPG sıkıştırma düzeyi (Ben son çıktıda kullandığınız varsayalım) imagejpeg() üçüncü parametresini kullanarak kalitesini artırabilir 100.

75 olduğunu

90-100 aralığında oynayın. Görüntü, dosya boyutunda orijinalden daha büyük olacaktır - bu, ödediğiniz fiyat olacaktır. Ancak karşılaştırılabilir kalitede elde etmek mümkün olmalıdır. Alternatif olarak, John Himmelman'ın yorumlarda zaten söylediği gibi, daha iyi kalite için imagepng()'u kullanmayı deneyin - tabii ki daha büyük bir dosya boyutunun fiyatı da.

+4

Merak eden herkes için son bir nokta. Imagejpeg() kalitesini 99 olarak değiştirdim ve çok daha iyi bir görüntü ile geldim. Her ne kadar - bu ve varsayılan arasındaki fark% 1000 dosyada artış (varsayılan 12kb'de geliyor, 110kb'de yüksek kaliteli sıkıştırma) – kalpaitch

+1

Sadece bunu okuduktan sonra geldiğim bir öneri. Minik resim sistemimde, küçük resmin görüntünün orijinal tam boyutlu görüntüyle aynı formatta olması gerekmediği için, yardımcı işlevime "bu resmin küçük resim dosyası nedir ve zaten var mı?" Sorusu sorulur. Bu yüzden file.jpg hakkında sorulduğunda, thumbnail_cache/file.jpg ile geri gelirdi. Bu yaklaşımı her zaman .png biçimindeki küçük resimlerle yanıtlamak için değiştirdim, bu yüzden file.jpg hakkında sorulursa, thumbnail_cache/file.png ile geri dönüp png minik resim oluşturur. Bu GD jpg sıkıştırma ile ilgili endişeleri önler. – Neek

1

, php.net belgeleri isterseniz size dest_image için imagecreatetruecolor() görüntü var gerektiğini söylüyor Sadece 255 renk paletini kullanmaktan kaçının, ancak bunu zaten yapıyorsunuz.

Bir alternatif, bir sistem() çağrısı ile imagemagick gibi harici bir araç kullanmak olacaktır.

+0

Evet, php'nin çok yardımcı olduğundan emin değilsiniz. Gördüğünüz gibi, imagecopyresized kullanarak üçüncü bir test görüntüsü yaptım, bu biraz daha iyi ama yeterli değil. – kalpaitch

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

bir kirli hüner etmektir hızlı imagecopyresized() üzerinde küçük resimleri 1000 x 1000 piksel (veya daha fazla) daha sonra imagejpeg($img, $savePath, 20); üzerinde 20 veya daha az JPEG kalitesi set olun. Çıkış genellikle 100 kb'dan daha küçük olacaktır.

İstemci CSS'nin yeniden boyutlandırmasını sağlayın ve resimler, küçük boyutlarına ölçeklendiğinde modern tarayıcılarda hızlı yüklenecek ve kusursuz görünecektir.

İlgili konular