How to Resize large images in PHP with Imagemagick

By | May 1, 2023

Resizing images

Web applications often need to work with images like pictures of users or photos etc. So the need to resize images comes up when creating thumbnails for example or compressing images for storage.

The default library to handle image operations in php is GD. It can be used to resize images.

GD vs Imagemagick: GD library uses ram memory to decode and encode images which becomes an issue when the image size is large and php runs out of available memory. On the other hand Imagemagick uses disk space to process the image data and can work with large size images easily.

Resize with GD

The function imagecopyresampled is used to resize an image with gd library.

Here is a quick example

function resize_image($src , $dest , $toWidth , $toHeight , $options = array()) 
{
	if(!file_exists($src))
	{
		die("$src file does not exist");
	}
	
	//OPEN THE IMAGE INTO A RESOURCE
	$img = imagecreatefromjpeg ($src);	//try jpg
	
	if(!$img)
	{
		$img = imagecreatefromgif ($src);	//try gif
	}
	
	if(!$img)
	{
		$img = imagecreatefrompng ($src);	//try png
	}
	
	if(!$img)
	{
		die("Could Not create image resource $src");
	}
	
	//ORIGINAL DIMENTIONS
	list( $width , $height ) = getimagesize( $src );
	
	//ORIGINAL SCALE
	$xscale=$width/$toWidth;
	$yscale=$height/$toHeight;
	
	//NEW DIMENSIONS WITH SAME SCALE
	if ($yscale > $xscale) 
	{
		$new_width = round($width * (1/$yscale));
		$new_height = round($height * (1/$yscale));
	}
	else 
	{
		$new_width = round($width * (1/$xscale));
		$new_height = round($height * (1/$xscale));
	}
	
	//NEW IMAGE RESOURCE
	if(!($imageResized = imagecreatetruecolor($new_width, $new_height)))
	{
		die("Could not create new image resource of width : $new_width , height : $new_height");
	}
	
	//RESIZE IMAGE
	if(! imagecopyresampled($imageResized, $img , 0 , 0 , 0 , 0 , $new_width , $new_height , $width , $height))
	{
		die('Resampling failed');
	}
	
	//STORE IMAGE INTO DESTINATION
	if(! imagejpeg($imageResized , $dest))
	{
		die("Could not save new file");
	}
	
	//Free the memory
	imagedestroy($img);
	imagedestroy($imageResized);
	
	return true;
}

The above program can resize a gif, jpg, or png image and the output is a jpg image.

However the above has some problems. If a jpg image for example , is 5000px x 5000px then imagecreatefromjpg would uncompress it and use a large amount of memory (5000 x 5000 pixels) to store it. This memory is taken from RAM or the memory allocated to php.

The amount of memory needed in uncompressed form can easily go upto several hundreds of MBs which is much higher than what php normally has access to on a typical web server depending on the configuration.

And then memory exceeded error might be thrown depending on how much memory is available to php.

Resize with Imagemagick

To overcome the memory problem, imagemagick is an excellent solution. Imagemagick can resize large images by using disk space instead of RAM memory.

Here is a quick example of how to resize an image using imagemagick library.

//Resize using imagemagick , it is memory efficient, GD fails since images are uncompressed.
try
{
	$img = new Imagick($old_path);
	$img->thumbnailImage(500 , 500 , TRUE);
	$img->writeImage($new_path);
	
	$count++;
}
catch(Exception $e)
{
	echo 'Caught exception: ',  $e->getMessage(), "n";
	$error++;
}

This should work where gd fails due to memory limitations.

Memory usage can be limited by using :

$img->setResourceLimit( Imagick::RESOURCETYPE_MEMORY, 5 );

Source

When memory limit is reached , disk space is used for memory.

Other ways of resizing images using imagemagick

<?php
/**
 * Calculate new image dimensions to new constraints
 *
 * @param Original X size in pixels
 * @param Original Y size in pixels
 * @return New X maximum size in pixels
 * @return New Y maximum size in pixels
 */
function scaleImage($x,$y,$cx,$cy) {
    //Set the default NEW values to be the old, in case it doesn't even need scaling
    list($nx,$ny)=array($x,$y);
    
    //If image is generally smaller, don't even bother
    if ($x>=$cx || $y>=$cx) {
            
        //Work out ratios
        if ($x>0) $rx=$cx/$x;
        if ($y>0) $ry=$cy/$y;
        
        //Use the lowest ratio, to ensure we don't go over the wanted image size
        if ($rx>$ry) {
            $r=$ry;
        } else {
            $r=$rx;
        }
        
        //Calculate the new size based on the chosen ratio
        $nx=intval($x*$r);
        $ny=intval($y*$r);
    }    
    
    //Return the results
    return array($nx,$ny);
}
?>

Use it like this:

<?php
//Read original image and create Imagick object
$thumb=new Imagick($originalImageFilename);

//Work out new dimensions
list($newX,$newY)=scaleImage(
        $thumb->getImageWidth(),
        $thumb->getImageHeight(),
        $newMaximumWidth,
        $newMaximumHeight);

//Scale the image
$thumb->thumbnailImage($newX,$newY);

//Write the new image to a file
$thumb->writeImage($thumbnailFilename);
?>
$fitbyWidth = (($maxWidth/$w)<($maxHeight/$h)) ?true:false;

if($fitbyWidth){
    $im->thumbnailImage($maxWidth, 0, false);
}else{
    $im->thumbnailImage(0, $maxHeight, false);
}

Maximum width and height

For example if the resized image should have a maximum width of 200px , and maximum height of 82 px , then the limits can be applied easily like this :

// Create thumbnail max of 200x82
$width=$im->getImageWidth();
if ($width > 200) 
{ 
    $im->thumbnailImage(200,null,0); 
}

//now check height
$height=$im->getImageHeight();
if ($height > 82) 
{ 
    $im->thumbnailImage(null,82,0); 
}

Links and Resources

1. Imagemagick tutorials - http://valokuva.org/?cat=1

2. http://www.php.net/manual/en/function.imagick-thumbnailimage.php

3. http://www.php.net/manual/en/book.imagick.php

About Silver Moon

A Tech Enthusiast, Blogger, Linux Fan and a Software Developer. Writes about Computer hardware, Linux and Open Source software and coding in Python, Php and Javascript. He can be reached at [email protected].

3 Comments

How to Resize large images in PHP with Imagemagick
  1. Reresize

    Dear Blogger

    I’m going to change my code from using GD to Imagemagick (Fred’s ImageMagick Scripts inspired me). What should I used to? Included in php ImageMagick or with system() command? What in your opinion is more efficient?

Leave a Reply

Your email address will not be published. Required fields are marked *