2010-02-26 156 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进行大小调整,当缩放到缩略图大小时,图片将快速加载并在现代浏览器中看起来完美无瑕。