How to Resize Image in PHP

PHP How To

Many times, you have to programmatically resize images. Maybe you have to create multiple sizes of the same image to serve on different devices. Maybe you need to resize images that your users are uploading. You can 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.

images/articles/php/resize-image-in-php.jpg

1. Load Image Before Resizing

The first step before you resize an image is loading it as an image resource inside the script. Loading the image will require to use different functions like

  • imagecreatefromjpeg()
  • imagecreatefrompng()
  • imagecreatefromgif()

The function you use will depend on the type of image you are resizing.

First, use the getimagesize() function to get important information about the image like its width, height and type. 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. Use the value of this returned constant to determine the type of image and appropriate function to use.

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 = "images/imagename.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. The list() function is used to assign values to multiple variables at once.

The load_image() function accepts two parameters, the path or URL of the image file and the image type. It applies an appropriate imagecreatefrom*() function based on the image type and returns the image resource identifier in the end.

2. Resize Image to Fixed Width and Height

After you have the image resource identifier, you 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 use the imagecopyresampled() function to copy and resize the original image over the new black one you just created.

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:

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)

Example:

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 = "images/imagename.jpg";
list($width, $height, $type) = getimagesize($filename);
$old_image = load_image($filename, $type);
$new_image = resize_image(280, 180, $old_image, $width, $height);

Since you 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 you obtained in the previous section while loading the old image.

3. Resize Image to Fixed Width while Maintaining 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 height is calculated automatically in order to maintain the aspect ratio.

function resize_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 = "images/imagename.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.

Pass the specified new width, calculated new height as well as the old image data to the resize_image() function you created in the previous section.

4. Resize Image to Fixed Height while Maintaining Aspect Ratio

The logic would be similar to calculating the height of the image for a specific width. The only difference is that you will be calculating the width of the image based on the given height.

function resize_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 = "images/imagename.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_to_height() function takes the new height and the original image with its width and height as parameters.

5. Scale Image by 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.

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 = "images/imagename.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, you 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 you defined earlier.

6. Save Resized Image

After resizing, it is time to save the resized image. You can 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 reduce the image size significantly.

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 = "images/imagename.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);

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.