How to resize an image and reduce quality in PHP without Imagick

You may want to resize the uploaded files of the user to save space on your server.

There are many ways to resize and decrease the quality of an image, and probably it would be better if you create your own function as it may fit better to your needs.

In this case, we are going to show you a way to resize your images and decrease the quality using plain PHP without use the Imagick library.

Resize image and return raw data

To resize an image from a file, use the following method. It supports the png, jpg and gif formats, you can extend the supported methods modifying the switch statement in the function.

/**
 * Resize image given a height and width and return raw image data.
 *
 * Note : You can add more supported image formats adding more parameters to the switch statement.
 *
 * @param type $file filepath
 * @param type $w width in px
 * @param type $h height in px
 * @param type $crop Crop or not
 * @return type
 */
function resize_image($file, $w, $h, $crop=false) {
    list($width, $height) = getimagesize($file);
    $r = $width / $height;
    if ($crop) {
        if ($width > $height) {
            $width = ceil($width-($width*abs($r-$w/$h)));
        } else {
            $height = ceil($height-($height*abs($r-$w/$h)));
        }
        $newwidth = $w;
        $newheight = $h;
    } else {
        if ($w/$h > $r) {
            $newwidth = $h*$r;
            $newheight = $h;
        } else {
            $newheight = $w/$r;
            $newwidth = $w;
        }
    }
    
    //Get file extension
    $exploding = explode(".",$file);
    $ext = end($exploding);
    
    switch($ext){
        case "png":
            $src = imagecreatefrompng($file);
        break;
        case "jpeg":
        case "jpg":
            $src = imagecreatefromjpeg($file);
        break;
        case "gif":
            $src = imagecreatefromgif($file);
        break;
        default:
            $src = imagecreatefromjpeg($file);
        break;
    }
    
    $dst = imagecreatetruecolor($newwidth, $newheight);
    imagecopyresampled($dst, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);

    return $dst;
}

The previous method returns in a variable the raw data from the image, therefore you need to save it manually according to the file type i.e :

$filename = "/var/www/images/mynormalimage.png";
$resizedFilename = "/var/www/images/myresizedimage.png";

// resize the image with 300x300
$imgData = resize_image($filename, 300, 300);
// save the image on the given filename
imagepng($imgData, $resizedFilename);
// or according to the original format, use another method
// imagejpeg($imgData, $resizedFilename);
// imagegif($imgData, $resizedFilename);

A really straight forward solution to resize quickly a normal image but note that is recommendable to use the logic of the previous function and implement a new one that matches with your need.

Reduce or increase quality

Note that with the imagejpeg, imagepng etc. methods you can specify the quality of the image in the third parameter with a numeric value (INT) :

// Get the data from a png file
$imageData = resize_image("myfolder/myfile.png",500,500);
// Give a name to your file with the full patj
$filepath = "myfolder/myresizedimage.png";
$quality = 0;

imagepng($imageData,$filepath,$quality);

Every save method support a third parameter which specifies the quality of the image. This value set the compression level: 0-9 or -1, where 0 is NO COMPRESSION at all, 1 is FASTEST but produces larger files, 9 provides the best compression (smallest files) but takes a long time to compress, and -1 selects the default compiled into the zlib library.

You can even create a compress method, like the following :

/**
 * Decrease or increase the quality of an image without resize it.
 * 
 * @param type $source
 * @param type $destination
 * @param type $quality
 * @return type
 */
function compress($source, $destination, $quality) {
    //Get file extension
    $exploding = explode(".",$source);
    $ext = end($exploding);

    switch($ext){
        case "png":
            $src = imagecreatefrompng($source);
        break;
        case "jpeg":
        case "jpg":
            $src = imagecreatefromjpeg($source);
        break;
        case "gif":
            $src = imagecreatefromgif($source);
        break;
        default:
            $src = imagecreatefromjpeg($source);
        break;
    }
    
    switch($ext){
        case "png":
            imagepng($src, $destination, $quality);
        break;
        case "jpeg":
        case "jpg":
            imagejpeg($src, $destination, $quality);
        break;
        case "gif":
            imagegif($src, $destination, $quality);
        break;
        default:
            imagejpeg($src, $destination, $quality);
        break;
    }

    return $destination;
}

It expects the filepath of the file that needs to be modified. The second parameter is the destination path of the file, it can be the same of the first parameter in order to replace it.

Info

Remember that there are many supported image types to process, PHP supports the following methods :

  • imagecreatefromgd.
  • imagecreatefromgd2.
  • imagecreatefromgd2part.
  • imagecreatefromgif.
  • imagecreatefromjpeg.
  • imagecreatefrompng.
  • imagecreatefromstring.
  • imagecreatefromwbmp.
  • imagecreatefromwebp.
  • imagecreatefromxbm.
  • imagecreatefromxpm.

And to create a image from the previous methods use :

  • imagegd.
  • imagegd2.
  • imagegd2part.
  • imagecreatefromgif.
  • imagejpeg.
  • imagepng.
  • imagestring.
  • imagewbmp.
  • imagewebp.
  • imagexbm.
  • imagexpm.

And respectively save methods with the prefix image<format>(imagefrom<format>,filepath). Have fun

Become a more social person