Best way to resize an image programmatically in PHP

If you are working on a website or project which deals with images, there will most probably come a time when you will have to programmatically resize those images. Maybe you have to create three different sizes of the same image to serve on different devices. Maybe you need to resize images that your users are uploading. Loading a 1920*1080 image when 96*54 image will do is just a waste of resources.

In this article, we will write different functions that will make use of the PHP’s GD library to resize images in PHP. GD has all the necessary functions to manipulate images so you won’t have to use any other 3rd party library.

On This Page — Loading the Image Before Resizing, Resize Image to Fixed Width and Height, Resize Image to Fixed Width While Maintaining the Aspect Ratio, Resize Image to Fixed Height While Maintaining the Aspect Ratio, Scale Image By a Given Factor, Save the Resized Image, The Complete PHP Code for Loading, Resizing and Saving Images and Quick Summary.

Loading the Image Before Resizing

The first step before we resize an image is loading it as an image resource inside the script. This is very different than using functions like file_get_contents() to get the content of the image file. Loading the image will require us to use different functions like imagecreatefromjpeg(), imagecreatefrompng() and imagecreatefromgif() etc. The function we use will depend on the type of image we are resizing.

We will use the getimagesize() function to get important information about the image like its width, height and type etc. This function returns an array with up to 7 elements. The width and height of the image are stored at index 0 and 1 respectively. The IMAGETYPE_XXX constants are stored at index 2 of the returned array. We will use the value of this returned constant to determine the type of image and appropriate function to use. Not all image types will return an array with seven elements upon calling getimagesize(). However, these three indices will definitely have their values populated. Here is some example code which loads an image from either a given path or given URL.

PHP

function load_image($filename, $type) {
    if( $type == IMAGETYPE_JPEG ) {
        $image = imagecreatefromjpeg($filename);
    }
    elseif( $type == IMAGETYPE_PNG ) {
        $image = imagecreatefrompng($filename);
    }
    elseif( $type == IMAGETYPE_GIF ) {
        $image = imagecreatefromgif($filename);
    }
    return $image;
}

$filename = "wallpapers/skyline.jpg";
list($width, $height, $type) = getimagesize($filename);
$old_image = load_image($filename, $type);

The $filename variable can contain either the path of the image or its URL. We have used the list() function to assign values to multiple variables at once.

The load_image() function that we defined accepts two parameters, the path or URL of the image file we want to load and the image type. It applies an appropriate imagecreatefrom*() function based on the image type and returns the image resource identifier in the end. We are only handling the loading of JPEG, PNG and GIF images in our case but you can include more image types.

Resize Image to Fixed Width and Height

Once we have the image resource identifier, we can use other GD functions to resize the image. The imagecreatetruecolor() function creates a new true color image with given width and height. The image created by this function will be all black so we will use the imagecopyresampled() function to copy and resize the original image over the new black one we just created using imagecreatetruecolor().

The imagecopyresampled() function accepts 10 different parameters. The first two parameters identify the new and old image resource respectively. The third and fourth parameters specify the x and y coordinates for the destination image where you want to start copying the image. The fifth and sixth parameters determine the x and y coordinates of the source image from where you want to start copying the original image data. The seventh and eighth parameters determine the width and height of the original image block that you want to copy to the new image. The ninth and tenth parameters determine the width and height of the new image where you are copying the old image. The syntax of this function looks like this:

PHP

bool imagecopyresampled ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )

Here is the example code that resamples the original image and resizes it to have the given dimensions.

PHP

function resize_image($new_width, $new_height, $image, $width, $height) {
    $new_image = imagecreatetruecolor($new_width, $new_height);
    imagecopyresampled($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
    return $new_image;
}

$filename = "wallpapers/skyline.jpg";
list($width, $height, $type) = getimagesize($filename);
$old_image = load_image($filename, $type);
$new_image = resize_image(280, 180, $old_image, $width, $height);

Since we want to copy and resize the whole image, the x and y coordinates for the source and destination have been set to zero. The resize_image() function returns a new image resource identifier which contains the resized image. The values passed to the resize_image() function are the ones that we obtained in the previous section while loading the old image.

Resize Image to Fixed Width While Maintaining the Aspect Ratio

The images that you are planning to resize can have different aspect ratios. This means that if you use the above resize_image() function to resize them, some of them will look distorted. If you want images to have a specific width while preserving the aspect ratio of the original image, you should first get the height of the image based on given width and aspect ratio.

The example code below resizes the original image to have a specific width. The height is calculated automatically in order to maintain the aspect ratio.

PHP

function resize_image_to_width($new_width, $image, $width, $height) {
    $resize_ratio = $new_width / $width;
    $new_height = $height * $resize_ratio;
    return resize_image($new_width, $new_height, $image, $width, $height);
}

$filename = "wallpapers/skyline.jpg";
list($width, $height, $type) = getimagesize($filename);
$old_image = load_image($filename, $type);
$image_width_fixed = resize_image_to_width(560, $old_image, $width, $height);

The resize_to_width() function takes the new width and the original image with its width and height as parameters. It calculates the resize ratio based on the new width and original width. This ratio needs to be maintained when calculating the new height of the image. For example, if the original image was 2880*1800 in size and you want the new image to be 576px wide, the resize ratio would be 576/2880 = 0.2. This ratio is then multiplied by original image height to get the new height. In our case, the new height will become 360px. We pass the specified new width, calculated new height as well as the old image data to the resize_image() function we created in the previous section.

Resize Image to Fixed Height While Maintaining the Aspect Ratio

If you plan to resize an image to a given height and want its width to be calculated automatically, you can use the example code in this section. The logic would be similar to calculating the height of the image for a specific width. The only difference is that we will be calculating the width of the image based on the given height.

Here is the example code that we will use to resize the image to given height.

PHP

function resize_image_to_height($new_height, $image, $width, $height) {
    $ratio = $new_height / $height;
    $new_width = $width * $ratio;
    return resize_image($new_width, $new_height, $image, $width, $height);
}

$filename = "wallpapers/skyline.jpg";
list($width, $height, $type) = getimagesize($filename);
$old_image = load_image($filename, $type);
$image_height_fixed = resize_image_to_height(900, $old_image, $width, $height);

In this case, resize_image_to_height() function takes the new height and the original image with its width and height as parameters.

Scale Image By a Given Factor

This is also a very common requirement when resizing images. This time, instead of specifying the width or height of new image, you specify the scale. If you want the new image size to be half the original image, you set the scale to 0.5. Here is the example code to scale an image by given factor while preserving the aspect ratio.

PHP

function scale_image($scale, $image, $width, $height) {
    $new_width = $width * $scale;
    $new_height = $height * $scale;
    return resize_image($new_width, $new_height, $image, $width, $height);
}

$filename = "wallpapers/skyline.jpg";
list($width, $height, $type) = getimagesize($filename);
$old_image = load_image($filename, $type);
$image_scaled = scale_image(0.8, $old_image, $width, $height);

Inside the scale_image() function, we just multiply the original width and height of the image with the given scale. All these values are then passed to the resize_image() function that we defined earlier.

Save the Resized Image

So far in the tutorial, we have learned how to resize an image to a given width and/or height or how to scale the image. Now it is time to save the resized image. We will use three GD library functions named imagejpeg(), imagepng() and imagegif() to save the image based on the specified type.

JPEG images can be saved with different amount of compression applied to them. This can help us reduce the image size significantly. The example code below will save the resized image based on specified parameters.

PHP

function save_image($new_image, $new_filename, $new_type='jpeg', $quality=80) {
    if( $new_type == 'jpeg' ) {
        imagejpeg($new_image, $new_filename, $quality);
     }
     elseif( $new_type == 'png' ) {
        imagepng($new_image, $new_filename);
     }
     elseif( $new_type == 'gif' ) {
        imagegif($new_image, $new_filename);
     }
}

$filename = "wallpapers/skyline.jpg";
list($width, $height, $type) = getimagesize($filename);
$old_image = load_image($filename, $type);
$new_image = resize_image(280, 180, $old_image, $width, $height);
save_image($new_image, 'wallpapers/resized-'.basename($filename), 'jpeg', 75);

The Complete PHP Code for Loading, Resizing and Saving Images

Here is the complete code for loading, resizing and saving JPEG, PNG or GIF images in PHP. I have reorganized the code and placed all the functions that we defined at the top.

PHP

function load_image($filename, $type) {
    if( $type == IMAGETYPE_JPEG ) {
        $image = imagecreatefromjpeg($filename);
    }
    elseif( $type == IMAGETYPE_PNG ) {
        $image = imagecreatefrompng($filename);
    }
    elseif( $type == IMAGETYPE_GIF ) {
        $image = imagecreatefromgif($filename);
    }
    return $image;
}

function resize_image($new_width, $new_height, $image, $width, $height) {
    $new_image = imagecreatetruecolor($new_width, $new_height);
    imagecopyresampled($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
    return $new_image;
}

function resize_image_to_width($new_width, $image, $width, $height) {
    $ratio = $new_width / $width;
    $new_height = $height * $ratio;
    return resize_image($new_width, $new_height, $image, $width, $height);
}

function resize_image_to_height($new_height, $image, $width, $height) {
    $ratio = $new_height / $height;
    $new_width = $width * $ratio;
    return resize_image($new_width, $new_height, $image, $width, $height);
}

function scale_image($scale, $image, $width, $height) {
    $new_width = $width * $scale;
    $new_height = $height * $scale;
    return resize_image($new_width, $new_height, $image, $width, $height);
}


function save_image($new_image, $new_filename, $new_type='jpeg', $quality=80) {
    if( $new_type == 'jpeg' ) {
        imagejpeg($new_image, $new_filename, $quality);
     }
     elseif( $new_type == 'png' ) {
        imagepng($new_image, $new_filename);
     }
     elseif( $new_type == 'gif' ) {
        imagegif($new_image, $new_filename);
     }
}


/* Testing the above code */

$filename = "wallpapers/skyline.jpg";
list($width, $height, $type) = getimagesize($filename);
$old_image = load_image($filename, $type);

$new_image = resize_image(280, 180, $old_image, $width, $height);
$image_width_fixed = resize_image_to_width(560, $old_image, $width, $height);
$image_height_fixed = resize_image_to_height(900, $old_image, $width, $height);
$image_scaled = scale_image(0.8, $old_image, $width, $height);

save_image($new_image, 'wallpapers/resized-'.basename($filename), 'jpeg', 75);
save_image($image_width_fixed, 'wallpapers/fixed-width-'.basename($filename), 'jpeg', 75);
save_image($image_height_fixed, 'wallpapers/fixed-height-'.basename($filename), 'jpeg', 75);
save_image($image_scaled, 'wallpapers/scaled-'.basename($filename), 'jpeg', 75);

In the above example, I have resized the same image to have fixed width and height, only have fixed width and only have fixed height. A fourth version of the image has also been scaled down to 0.8 times the original size.

You can use the same code to resize images uploaded by a user and resize all images in a directory by iterating over them one by one using the glob() function.

Quick Summary

Let’s recap everything that we have covered in this tutorial.

  1. The first thing that you need to do before you can resize an image is to load it in the script using functions like imagecreatefromjpeg(), imagecreatefrompng() and imagecreatefromgif() etc. based on the image type.
  2. You can resize the loaded image to have a fixed width and height by first creating a black image with the imagecreatetruecolor() function and then copying the pixels of the original image on this new blank image using the imagecopyresampled() function.
  3. If you want the resized image to have a fixed width but automatically calculate its height in order to preserve the aspect ratio, you should first calculate the ratio of new width to old width and then multiply the old height with this ratio. The same technique can be applied to resize images to a fixed height.
  4. If you want to scale the original image by a given factor, you can simply calculate the new width and height by multiplying the originals with given scale value. After that, you can just follow step 2 in order to resize the image.

Let me know if there is anything that you would like me to clarify. Also, you are more than welcome to comment if you know other techniques resize an image programmatically in PHP.

Reader Comments

1. You can register or login to post a comment. Asking readers to register improves the quality of discussion.

2. As a registered user, you will also get to access features like choosing between a light and dark theme or anything else that we might implement in future.

Follow Us For Updates

FacebookTwitterGoogle+
Go To Top