0

I am resizing images via PHP but they are coming out distorted. The code I am using is below.

I have edited the quality score from 80 but this has not changed the quality in any way

There maybe be a better way of doing this and any suggestions would be helpful

// Image resize function with php + gd2 lib
function imageresize($source, $destination, $width = 0, $height = 0, $crop = false,     $quality = 80) {
$quality = $quality ? $quality : 80;
$image = imagecreatefromstring($source);
if ($image) {
    // Get dimensions
    $w = imagesx($image);
    $h = imagesy($image);
    //die(json_encode(array('width' => $w, 'height' => $h)));
    if (($width && $w > $width) || ($height && $h > $height)) {
        $ratio = $w / $h;
        if (($ratio >= 1 || $height == 0) && $width && !$crop) {
            $new_height = $width / $ratio;
            $new_width = $width;
        } elseif ($crop && $ratio <= ($width / $height)) {
            $new_height = $width / $ratio;
            $new_width = $width;
        } else {
            $new_width = $height * $ratio;
            $new_height = $height;
        }
    } else {
        $new_width = $w;
        $new_height = $h;
    }
    $x_mid = $new_width * .5;  //horizontal middle
    $y_mid = $new_height * .5; //vertical middle
    // Resample
    error_log('height: ' . $new_height . ' - width: ' . $new_width);
    $new = imagecreatetruecolor(floor($new_width), floor($new_height));
    $x = 0;
    if ($new_width > $new_height) {
        //$new_height = $new_height *8;
    } else {
        //$x = -$new_width * 7;
        //$new_width = $new_width *8;
    }
    imagecopyresampled($new, $image, 0, 0, $x, 0, $new_width, $new_height, $w, $h);
    // Crop
    if ($crop) {
        $crop = imagecreatetruecolor($width ? $width : $new_width, $height ? $height : $new_height);
        imagecopyresampled($crop, $new, 0, 0, ($x_mid - ($width * .5)), 0, $width, $height, $width, $height);
        //($y_mid - ($height * .5))
    }
    // Output
    // Enable interlancing [for progressive JPEG]
    imageinterlace($crop ? $crop : $new, true);

    $dext = strtolower(pathinfo($destination, PATHINFO_EXTENSION));
    if ($dext == '') {
        $dext = $ext;
        $destination .= '.' . $ext;
    }
    switch ($dext) {
        case 'jpeg':
        case 'jpg':
            imagejpeg($crop ? $crop : $new, $destination, $quality);
            break;
        case 'png':
            $pngQuality = ($quality - 100) / 11.111111;
            $pngQuality = round(abs($pngQuality));
            imagepng($crop ? $crop : $new, $destination, $pngQuality);
            break;
        case 'gif':
            imagegif($crop ? $crop : $new, $destination);
            break;
    }
    @imagedestroy($image);
    @imagedestroy($new);
    @imagedestroy($crop);
}
Andy Lester
  • 91,102
  • 13
  • 100
  • 152
Chris Campbell
  • 91
  • 2
  • 11
  • 1
    Do you have an example of before and after quality? – Matthew Jan 20 '14 at 16:14
  • 1
    If the original source file is low quality and/or low resolution, then you're going to end up with a low quality image. Use a higher resolution source file. – Funk Forty Niner Jan 20 '14 at 16:18
  • code looks correct, check the quality variable before outputing the image, maybe somehow you're passing very low quality. Try to remove to imageinterlace() and then test it, maybe this call decreases image quality. Then there is a small issue in your code, you're mixing variables. $crop variable at the begining is bool (function argument), then you're overwriting it to image, end at the end you're destryoing it with imagedestroy. so If someone will pass you false you will call imagedestroy() with false. – PolishDeveloper Jan 20 '14 at 16:20
  • What format are your beginning images in? Gif? Jpg? Png? I've had the most success with large JPG files as my original. – Dutchie432 Jan 20 '14 at 16:25
  • How are you viewing the images? In html page or on your disk? – ssaltman Jan 20 '14 at 16:31

0 Answers0