php imagecopyresampled низкого качества

У меня есть php-скрипт, который сохраняет исходное изображение, а затем изменяет его размер – одно миниатюру и одно увеличенное изображение для просмотра в Интернете. Это хорошо работает, но с некоторыми изображениями качество ужасное. Кажется, он сохранен с очень низким цветовым поддоном. Вы можете увидеть результат на http://kalpaitch.com/index.php?filter=white – щелкните по первому миниатюре с заголовком «белый белый белый»

Ниже приведен код, используемый для повторной выборки изображения:

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; 

Большое спасибо

PS [фотографии удалены с сервера]

И вот остальная часть кода загрузки:

 // 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); } 

Потеря качества снижается не до imagecopyresampled() , а к сжатию JPEG. К сожалению, алгоритмы сжатия GD не соответствуют Photoshop – на самом деле их очень мало. Но вы можете улучшить результат: уровень сжатия по умолчанию JPG по умолчанию составляет 75 из 100.

Вы можете повысить качество, используя третий параметр, к imagejpeg () (который, как я полагаю, вы используете для окончательного вывода):

 imagejpeg ( $new_image, null, 99); 

Играйте в диапазоне 90-100. Изображение будет больше размера файла, чем оригинал – это будет цена, которую вы платите. Но должно быть возможно достичь сопоставимого качества.

В качестве альтернативы, как говорит Джон Химмельман в комментариях, попробуйте использовать imagepng() для лучшего качества – конечно же, по цене значительно большего размера файла.

хорошо, документация php.net говорит, что у вас должно быть изображение imagecreatetruecolor () для вашего dest_image, если вы хотите избежать использования только цветовой палитры 255, но вы уже это сделали.

Я предполагаю, что альтернативой будет использование внешних инструментов, таких как imagemagick с вызовом system ().

 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; }