Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

php imagecopyresampled poor quality

Tags:

php

image

I have a php script which saves the original image, then resizes it - one thumbnail and one larger image for web viewing. This works well except with some images the quality is terrible. It seems to be saved with a very low colour pallet. You can see the result at http://kalpaitch.com/index.php?filter=white - click on the first thumbnail with the title 'white white white'

Below is the code used for the image resampling:

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;

Many Thanks

P.S. [photos removed from server]

And here is the rest of the upload code:

// 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);
        }
like image 275
kalpaitch Avatar asked Feb 26 '10 23:02

kalpaitch


2 Answers

well, php.net documentation says you should have a imagecreatetruecolor() image for your dest_image if you want to avoid using only a 255 color palette but you already do that.

I guess an alternative would be to use an external tools such as imagemagick with a system() call.

like image 122
Mathieu Avatar answered Oct 13 '22 00:10

Mathieu


The loss in quality is down not to imagecopyresampled(), but to the JPEG compression. Unfortunately, GD's compression algorithms are no match to Photoshop's - in fact, very few are. But you can improve the result: GD's default JPG compression level is 75 of 100.

You can raise the quality using the third parameter to imagejpeg() (which I assume you are using for the final output):

imagejpeg  ( $new_image, null, 99);

Play around in the 90-100 range. The image will become larger in file size than the original - that is going to be the price you pay. But it should be possible to achieve comparable quality.

Alternatively, as John Himmelman already says in the comments, try using imagepng() for better quality - also at the price of a notably larger file size, of course.

like image 36
Pekka Avatar answered Oct 12 '22 23:10

Pekka