Image Resizing Made Easy with PHP

Image Resizing Made Easy with PHP

Tutorial Details
  • Estimated Completion Time: 40 minutes
  • Difficulty: Intermediate
  • Technology: PHP 5

Ever wanted an all purpose, easy to use method of resizing your images in PHP? Well that’s what PHP classes are for – reusable pieces of functionality that we call to do the dirty work behind the scenes. We’re going to learn how to create our own class that will be well constructed, as well as expandable. Resizing should be easy. How easy? How about three steps!


Introduction

To give you a quick glimpse at what we’re trying to achieve with our class, the class should be:

  • Easy to use
  • Format independent. I.E., open, resize, and save a number of different images formats.
  • Intelligent sizing – No image distortion!

Note: This isn’t a tutorial on how to create classes and objects, and although this skill would help, it isn’t necessary in order to follow this tutorial.

There’s a lot to cover – Let’s begin.


Step 1 Preparation

We’ll start off easy. In your working directory create two files: one called index.php, the other resize-class.php


Step 2 Calling the Object

To give you an idea of what we’re trying to achieve, we’ll begin by coding the calls we’ll use to resize the images. Open your index.php file and add the following code.

As you can see, there is a nice logic to what we’re doing. We open the image file, we set the dimensions we want to resize the image to, and the type of resize.
Then we save the image, choosing the image format we want and the image quality. Save and close your index.php file.

		// *** Include the class
		include("resize-class.php");

		// *** 1) Initialize / load image
		$resizeObj = new resize('sample.jpg');

		// *** 2) Resize image (options: exact, portrait, landscape, auto, crop)
		$resizeObj -> resizeImage(150, 100, 'crop');

		// *** 3) Save image
		$resizeObj -> saveImage('sample-resized.gif', 100);

From the code above you can see we’re opening a jpg file but saving a gif. Remember, it’s all about flexibility.


Step 3 Class Skeleton

It’s Object-Oriented Programming (OOP) that makes this sense of ease possible. Think of a class like a pattern; you can encapsulate the data – another jargon term that really just means hiding the data. We can then reuse this class over and over without the need to rewrite any of the resizing code – you only need to call the appropriate methods just as we did in step two. Once our pattern has been created, we create instances of this pattern, called objects.

“The construct function, known as a constructor, is a special class method that gets called by the class when you create a new object.”

Let’s begin creating our resize class. Open your resize-class.php file. Below is a really basic class skeleton structure which I’ve named ‘resize’. Note the class variable comment line; this is were we’ll start adding our important class variables later.

The construct function, known as a constructor, is a special class method (the term “method” is the same as function, however, when talking about classes and objects the term method is often used) that gets called by the class when you create a new object. This makes it suitable for us to do some initializing – which we’ll do in the next step.

		Class resize
		{
			// *** Class variables

			public function __construct()
			{

			}
		}

Note that’s a double underscore for the construct method.


Step 4 The Constructor

We’re going to modify the constructor method above. Firstly, we’ll pass in the filename (and path) of our image to be resized. We’ll call this variable $fileName.

We need to open the file passed in with PHP (more specifically the PHP GD Library) so PHP can read the image. We’re doing this with the custom method ‘openImage’. I’ll get to how this method
works in a moment, but for now, we need to save the result as a class variable. A class variable is just a variable – but it’s specific to that class. Remember the class variable comment I mentioned previously? Add ‘image’ as a private variable by typing ‘private $image;’. By setting the variable as ‘Private’ you’re setting the scope of that variable so it can only be accessed by the class. From now on we can make a call to our opened image, known as a resource, which we will be doing later when we resize.

While we’re at it, let’s store the height and width of the image. I have a feeling these will be useful later.

You should now have the following.

		Class resize
		{
			// *** Class variables
			private $image;
			private $width;
			private $height;

			function __construct($fileName)
			{
			    // *** Open up the file
			    $this->image = $this->openImage($fileName);

			    // *** Get width and height
			    $this->width  = imagesx($this->image);
			    $this->height = imagesy($this->image);
			}
		}

Methods imagesx and imagesy are built in functions that are part of the GD library. They retrieve the width and height of your image, respectively.


Step 5 Opening the Image

In the previous step, we call the custom method openImage. In this step we’re going to create that method. We want the script to do our thinking for us, so depending on what file type is passed in, the script should determine what GD Library function it calls to open the image. This is easily achieved by comparing the files extension with a switch statement.

We pass in our file we want to resize and return that files resource.

		private function openImage($file)
		{
		    // *** Get extension
		    $extension = strtolower(strrchr($file, '.'));

		    switch($extension)
		    {
		        case '.jpg':
		        case '.jpeg':
		            $img = @imagecreatefromjpeg($file);
		            break;
		        case '.gif':
		            $img = @imagecreatefromgif($file);
		            break;
		        case '.png':
		            $img = @imagecreatefrompng($file);
		            break;
		        default:
		            $img = false;
		            break;
		    }
		    return $img;
		}

Step 6 How to Resize

This is where the love happens. This step is really just an explanation of what we’re going to do – so no homework here. In the next step, we’re going to create a public method that we’ll call to perform our resize; so it makes sense to pass in the width and height, as well as information about how we want to resize the image. Let’s talk about this for a moment. There will be scenarios where you would like to resize an image to an exact size. Great, let’s include this. But there will also be times when you have to resize hundreds of images and each image has a different aspect ratio – think portrait images. Resizing these to an exact size will cause severe distortion.If we take a look at our options to prevent distortion we can:

  1. Resize the image as close as we can to our new image dimensions, while still keeping the aspect ratio.
  2. Resize the image as close as we can to our new image dimensions and crop the remainder.

Both options are viable, depending on your needs.

Yep. we’re going to attempt to handle all of the above. To recap, we’re going to provide options to:

  1. Resize by exact width/height. (exact)
  2. Resize by width – exact width will be set, height will be adjusted according to aspect ratio. (landscape)
  3. Resize by height – like Resize by Width, but the height will be set and width adjusted dynamically. (portrait)
  4. Auto determine options 2 and 3. If you’re looping through a folder with different size photos, let the script determine how to handle this. (auto)
  5. Resize, then crop. This is my favourite. Exact size, no distortion. (crop)

Step 7 Resizing. Let’s do it!

There are two parts to the resize method. The first is getting the optimal width and height for our new image by creating some custom methods – and of course passing in our resize ‘option’ as described above. The width and height are returned as an array and set to their respective variables. Feel free to ‘pass as reference’- but I’m not a huge fan of that.

The second part is what performs the actual resize. In order to keep this tutorial size down, I’ll let you read up on the following GD functions:

We also save the output of the imagecreatetruecolor method (a new true color image) as a class variable. Add ‘private $imageResized;’ with your other class variables.

Resizing is performed by a PHP module known as the GD Library. Many of the methods we’re using are provided by this library.

		// *** Add to class variables
		private $imageResized;
		public function resizeImage($newWidth, $newHeight, $option="auto")
		{

			// *** Get optimal width and height - based on $option
			$optionArray = $this->getDimensions($newWidth, $newHeight, strtolower($option));

			$optimalWidth  = $optionArray['optimalWidth'];
			$optimalHeight = $optionArray['optimalHeight'];

			// *** Resample - create image canvas of x, y size
			$this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
			imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);

			// *** if option is 'crop', then crop too
			if ($option == 'crop') {
				$this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
			}
		}

Step 8 The Decision Tree

The more work you do now, the less you have to do when you resize. This method chooses the route to take, with the goal of getting the optimal resize width and height based on your resize option. It’ll call the appropriate method, of which we’ll be creating in the next step.

		private function getDimensions($newWidth, $newHeight, $option)
		{

		   switch ($option)
		    {
		        case 'exact':
		            $optimalWidth = $newWidth;
		            $optimalHeight= $newHeight;
		            break;
		        case 'portrait':
		            $optimalWidth = $this->getSizeByFixedHeight($newHeight);
		            $optimalHeight= $newHeight;
		            break;
		        case 'landscape':
		            $optimalWidth = $newWidth;
		            $optimalHeight= $this->getSizeByFixedWidth($newWidth);
		            break;
		        case 'auto':
		            $optionArray = $this->getSizeByAuto($newWidth, $newHeight);
					$optimalWidth = $optionArray['optimalWidth'];
					$optimalHeight = $optionArray['optimalHeight'];
		            break;
				case 'crop':
		            $optionArray = $this->getOptimalCrop($newWidth, $newHeight);
					$optimalWidth = $optionArray['optimalWidth'];
					$optimalHeight = $optionArray['optimalHeight'];
		            break;
		    }
			return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
		}

Step 9 Optimal Dimensions

We’ve already discussed what these four methods do. They’re just basic maths, really, that calculate our best fit.

		private function getSizeByFixedHeight($newHeight)
		{
		    $ratio = $this->width / $this->height;
		    $newWidth = $newHeight * $ratio;
		    return $newWidth;
		}

		private function getSizeByFixedWidth($newWidth)
		{
		    $ratio = $this->height / $this->width;
		    $newHeight = $newWidth * $ratio;
		    return $newHeight;
		}

		private function getSizeByAuto($newWidth, $newHeight)
		{
		    if ($this->height < $this->width)
		    // *** Image to be resized is wider (landscape)
		    {
		        $optimalWidth = $newWidth;
		        $optimalHeight= $this->getSizeByFixedWidth($newWidth);
		    }
		    elseif ($this->height > $this->width)
		    // *** Image to be resized is taller (portrait)
		    {
		        $optimalWidth = $this->getSizeByFixedHeight($newHeight);
		        $optimalHeight= $newHeight;
		    }
			else
		    // *** Image to be resizerd is a square
		    {
				if ($newHeight < $newWidth) {
					$optimalWidth = $newWidth;
					$optimalHeight= $this->getSizeByFixedWidth($newWidth);
				} else if ($newHeight > $newWidth) {
					$optimalWidth = $this->getSizeByFixedHeight($newHeight);
				    $optimalHeight= $newHeight;
				} else {
					// *** Sqaure being resized to a square
					$optimalWidth = $newWidth;
					$optimalHeight= $newHeight;
				}
		    }

			return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
		}

		private function getOptimalCrop($newWidth, $newHeight)
		{

			$heightRatio = $this->height / $newHeight;
			$widthRatio  = $this->width /  $newWidth;

			if ($heightRatio < $widthRatio) {
				$optimalRatio = $heightRatio;
			} else {
				$optimalRatio = $widthRatio;
			}

			$optimalHeight = $this->height / $optimalRatio;
			$optimalWidth  = $this->width  / $optimalRatio;

			return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
		}

Step 10 Crop

If you opted in for a crop – that is, you’ve used the crop option, then you have one more little step. We’re going to crop the image from the
center. Cropping is a very similar process to resizing but with a couple more sizing parameters passed in.

		private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
		{
			// *** Find center - this will be used for the crop
			$cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
			$cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );

			$crop = $this->imageResized;
			//imagedestroy($this->imageResized);

			// *** Now crop from center to exact requested size
			$this->imageResized = imagecreatetruecolor($newWidth , $newHeight);
			imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
		}

Step 11 Save the Image

We’re getting there; almost done. It’s now time to save the image. We pass in the path, and the image quality we would like ranging from 0-100, 100 being the best, and call the appropriate method. A couple of things to note about the image quality: JPG uses a scale of 0-100, 100 being the best. GIF images don’t have an image quality setting. PNG’s do, but they use the scale 0-9, 0 being the best. This isn’t good as we can’t expect ourselves to remember this every time we want to save an image. We do a bit of magic to standardize everything.

		public function saveImage($savePath, $imageQuality="100")
		{
			// *** Get extension
        	$extension = strrchr($savePath, '.');
        	$extension = strtolower($extension);

			switch($extension)
			{
				case '.jpg':
				case '.jpeg':
					if (imagetypes() & IMG_JPG) {
						imagejpeg($this->imageResized, $savePath, $imageQuality);
					}
		            break;

				case '.gif':
					if (imagetypes() & IMG_GIF) {
						imagegif($this->imageResized, $savePath);
					}
					break;

				case '.png':
					// *** Scale quality from 0-100 to 0-9
					$scaleQuality = round(($imageQuality/100) * 9);

					// *** Invert quality setting as 0 is best, not 9
					$invertScaleQuality = 9 - $scaleQuality;

					if (imagetypes() & IMG_PNG) {
						imagepng($this->imageResized, $savePath, $invertScaleQuality);
					}
					break;

				// ... etc

				default:
					// *** No extension - No save.
					break;
			}

			imagedestroy($this->imageResized);
		}

Now is also a good time to destroy our image resource to free up some memory. If you were to use this in production, it might also be a good idea to capture and return the result of the saved image.


Conclusion

Well that’s it, folks. Thank you for following this tutorial, I hope you find it useful. I’d appreciate your feedback, via the comments below.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://gdansk.esn.pl misiek

    Nice work!
    But i was missing an alpha channel for PNG, so I just added it to your code. Now transparent images are correctly resized without loosing this important information.

    Here’s what I’ve done:

    in resizeImage and crop methods:

    (…)
    $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);

    // *** Resample – create image canvas of x, y size
    if (imagetypes() & IMG_PNG) {
    imagesavealpha($this->imageResized, true);
    imagealphablending($this->imageResized, false);
    }

    imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);
    (..)

    as you can it was only one simple if statement in 2 places in code.
    Once again thanks a lot.

    Cheers

    • HADI

      @misiek thanks i was looking for that.

    • Luís Carvalho

      Thanks, thanks, thanks!!!

      You made my day! ;)

    • Omprakash

      Hi I am facing problem while .png file . How can i fill it with white background color. I didn’t understanding where to put that code

    • loque

      Hmmm I can’t make it work, could you post the entire modified code of resize-class.php… or send it to my address loque [at] loquenahak.net? Much appreciated!

  • gabriel

    Cool! Here is modified version of the openImage method that not depends of
    file extension:

    private function openImage($file)
    {
    // Image info
    $info = getimagesize($file);

    if ($this->info) {
    switch ($this->info[2]) {
    case IMAGETYPE_PNG:
    return imagecreatefrompng($image);
    case IMAGETYPE_JPEG:
    return imagecreatefromjpeg($image);
    case IMAGETYPE_GIF:
    return imagecreatefromgif($image);
    }
    }

    return false;
    }

    • ndtreviv

      Great!
      I was going to say: It’s ill-advised to rely on an image extension. You can’t guarantee that the user didn’t mess the extension up, that it even has an extension (some OS-s, such as Mac OS X, don’t require an extension to recognize the file, but use the “magic numbers” instead), or in the case of the code in the tutorial: that there isn’t more than one “.” in the file name.

      I think it’s worth updating your tutorial with the code supplied by gabriel.

  • Attila Kis

    Hi, I have a cusetion.

    $resizeObj = new resize(‘sample.jpg’);

    how can I make with variable in plase of picture?

    $resizeObj = new resize(‘$mypicture’); its not working like this.

    thank you for your answers.

    • http://www.marciano.com.mx Fernando

      $mypicture = ‘sample.jpg’;
      $resizeObj = new resize($mypicture);

      cheers!

  • Attila Kis

    And another cuestion….

    $resizeObj -> saveImage(‘sample-resized.jpg’, 100);

    I would like to be save the thumb in to an folder, something like this —->

    $resizeObj -> saveImage(‘myfolder/$thumbname’, 100); <— its not working like this

    something sugestion?

    thank you for your answers

    • Devon Adkisson

      To answer both of your questions, use double quotes instead of single quotes, like so:

      $resizeObj = new resize(“$mypicture”);

      Since it’s just the variable there, you could also just remove the quotes entirely:

      $resizeObj = new resize($mypicture);

      Double quotes again:

      $resizeObj -> saveImage(“myfolder/$thumbname”, 100);

      To use variables in a string, use double quotes. To use word for word, use single quotes.

      Alternatively, you could concatenate the strings like so:

      $resizeObj -> saveImage(‘myfolder/’ . $thumbname, 100); the . adds the two strings together.

  • Emilio

    nice tutorial… its nice to see tutorial made it in Linux :D

  • Andy Schuler

    Thank you for this library. It’s worked like a champ for me.

    I added one more option type for the resize because I needed one to make sure the image always stayed under either the height or width specified. So if you specify an image as 1000×200, it’ll never be more than 200px high and never more than 1000px wide.

    I called it “safe”, here’s the method:

    private function getSizeBySafe($newWidth, $newHeight) {
    if($newWidth >= $this->width && $newHeight >= $this->height) {
    //we’re just going to return the original
    return array(‘optimalWidth’ => $this->width, ‘optimalHeight’ => $this->height);
    }
    if($newWidth >= $this->width && $newHeight height ) {
    //so we are height bound
    return array(‘optimalWidth’ => $this->getSizeByFixedHeight($newHeight), ‘optimalHeight’ => $newHeight);
    }
    if($newHeight >= $this->height && $newWidth width ) {
    //so we are width bound
    return array(‘optimalWidth’ => $newWidth, ‘optimalHeight’ => $this->getSizeByFixedWidth($newWidth));
    }
    return $this->getSizeByAuto($newWidth, $newHeight);
    }

    Again, thanks for taking the time to put this together. It was exactly what I was looking for.

    • Buddy

      Great Andy! The missing link!
      However, if both height and width are oversize, there is still a problem. I tried running it twice, using the array variables the second time, but still to no avail. That did not seem to make a difference, for some reason.

      Perhaps I;m missing something in:
      if($newWidth >= $this->width && $newHeight height )
      AND
      if($newHeight >= $this->height && $newWidth width )
      Which are obviously incorrect, but I’m not bright enough to figure out what you meant there. :0) I eliminated the second half of these phrases.

      After running, I saved the two array values to variables:
      $optimalWidth = $optionArray['optimalWidth'];
      $optimalHeight = $optionArray['optimalHeight'];

      $optionArray = $this->getSizeBySafe($optimalWidth,$optimalHeight);

      • Buddy

        (This comment saved prematurely for some reason)

        Anyway, as you can see, I ran it again, hoping to clear up the height issue, which was still too big, but no luck.

  • http://www.fungamesarena.com Fun

    Very helpful and useful class, I resized all of my images.
    Thanks a lot…

  • ok

    LOL LOL LOL LOL

  • Albert

    Thanks Devon for this piece of code. Just two minor issues:

    The link to your source code doesn’t work. After typing everything over (more like copying, hiehie), it didn’t work (gave me a few errors). So I tried the link and found it was dead.

    Second problem is the more serious one:

    This is my code calling the function:

    $resizeObj = new resize(“$photoPath”);
    // *** 2) Resize image (options: exact, portrait, landscape, auto, crop)
    $resizeObj -> resizeImage(200, 200, ‘auto’);
    $resizeObj -> saveImage(“$photoPath”, 100);

    When I echo $photoPath at this stage, it is 100% correct: “staff/FILENAME.JPG”

    I get the following 3 errors:

    Warning: imagesx() expects parameter 1 to be resource, boolean given in xxxxxxxxxxxxxxxxxxxxxxx\dynam_code\resize.php on line 209

    Warning: imagesy() expects parameter 1 to be resource, boolean given in xxxxxxxxxxxxxxxxxxxxxxx\dynam_code\resize.php on line 210

    Warning: imagecopyresampled() expects parameter 2 to be resource, boolean given in xxxxxxxxxxxxxxxxxxxxxxx\dynam_code\resize.php on line 42

    Any suggestions to what it might be?

    • http://www.lcbcchurch.com Nate Hamilton

      I’m getting the same exact errors, did you figure out a fix to this yet?

  • Albert

    Oops, I meant thanks Jarrod…

  • http://www.zamshed.info Zamshed Farhan

    Nice. I am searching for this type of article very very eagerly. Thnx to author.

  • http://www.drupaltoronto.com Ibrahim

    Excellent. Thanks for sharing.

  • http://www.consak.ca AK

    Very good article. Thank you.

  • http://www.landonp.com Landon Poburan

    I am experiencing the same issue right now. I used this script about 2 months ago and it worked great and now working with it again and I have the exact same ‘imagesx’ and ‘imagesy’ issue. Also have:

    Fatal error: Call to undefined function resizeimage() in /mnt/stor1-wc2-dfw1/449915/www.dcc-staging.info/web/content/caep/businessesforsale/user/listing_new.php on line 136

    • http://kurkit.lt Tautvydas

      Me too. But not with all files. With some it works fine, with others don’t. It looks like a problem is with JPG files only.

      Warning: imagesx(): supplied argument is not a valid Image resource in resize-class.php on line 34

      Warning: imagesy(): supplied argument is not a valid Image resource in resize-class.php on line 35

      Warning: imagecopyresampled(): supplied argument is not a valid Image resource in resize-class.php on line 82

  • bob

    any chance you could explain how to save the image to a different directory – i got it working by using saveImage(‘./new/sample.jpg’ but that only saves to a directory below the script – when i try something like saveImage(‘/home/myhost/myuploadfolder/sample.jpg’ it fails

    great tutorial

    • bob

      must have been doing something wrong – got it working – thanks – great class/tutorial

  • http://www.agustawan.com agus tawan

    thank, this is very good

  • http://akhmads.com Akhmad

    Thanks! I use for Atk framework… and it works…
    Regard,
    Akhmad

  • http://www.brettwidmann.com Brett Widmann

    Very nice tutorial. Works great. Keep posting please!

  • Hussain

    I love this script, extremely professional… Very appreciated, thank you so much.

  • dual3nigma

    Thanks for sharing! Excellent tutorial! =)

  • JayApp

    Can someone show me a demo or something of what physically happens when this code is applied?

  • Muhammad nadeem

    Hi ,
    I just want to know that how much memory limit require by this script and what is maximum limit of image size which can be uploaded using this script

  • http://ikeif.net Keith

    I just grabbed this script for a quick little test on several images (366×478) and resized them to 121×162 – worked like a charm!

    Thanks!

  • WebDev

    Hey I was wondering if someone could help me out! I have a database of images, and wanted to test this code on resourcing the images from the database. So far I got the code up and running from a saved image, but is there any way I could take an image from a url, resize it, and then save it?

    Thanks!

    • WebDev

      *resizing not resourcing

  • http://downtownsanclemente.com John Albu

    Hello,
    I’m a website designer how do i put this to work in a webpage?
    Thank You in Advance!

  • http://www.frankandsense.com thecommonthread

    Great PHP class, but I think I may have found a serious problem? The images that I resize are all smaller in dimensions, but the file sizes stay exactly the same.

    • http://www.frankandsense.com thecommonthread

      Ah jeez, never mind, got it to work. Wish I could delete my comment now…

  • http://www.pentawebexperts.com Penta Web Experts

    Really nice tutorial. Well written, precise and of good standard.

    Keep sharing.

  • http://www.photogabble.co.uk Simon

    For some reason the files this resizes have a blurred edge even with quality set to 100, how come?

  • dimitri

    Great class!
    However I have a problem with images over 2MB, any image under this size works fine.

    Anyone got a answer or solution to this problem?

  • Vika

    Thanks, It was very useful.

  • http://www.its-unique.com Will

    First, really nice job of creating a class that simplifies access to the GD for resizing images. Second, really nice tutorial explaining said class.

    My problem lies with a strange issue and I simply do not know enough to fix it myself.

    I can create multiple resized images from a single source file with no problem but when I change files within the same script I never come back from trying to create the new class of the object. Interestingly, when I create the new class using a copy of the first image file, it works fine. I know that all the image files are good as I can process them one at a time and everything works.

    I feel like I would need to understand a lot more about both the Resize class (and GD) to figure this out and am hoping that someone will help save me the trouble!

    Will

  • chrishoward

    OMFG!!!!! Jarrod – you freakin legend! This looks like finally freeing me from timthumb!! And it cuts images to the exact size, shape and crop I want!! Freakin brilliant!

  • harry

    ( ! ) Warning: imagesx() expects parameter 1 to be resource, boolean given in E:\wamp\www\resize_img\resize-class.php on line 34
    Call Stack
    # Time Memory Function Location
    1 0.0001 365664 {main}( ) ..\index.php:0
    2 0.0007 427416 resize->__construct( ) ..\index.php:7
    3 0.0311 427736 imagesx ( ) ..\resize-class.php:34

    ( ! ) Warning: imagesy() expects parameter 1 to be resource, boolean given in E:\wamp\www\resize_img\resize-class.php on line 35
    Call Stack
    # Time Memory Function Location
    1 0.0001 365664 {main}( ) ..\index.php:0
    2 0.0007 427416 resize->__construct( ) ..\index.php:7
    3 0.0313 427768 imagesy ( ) ..\resize-class.php:35

    ( ! ) Warning: Division by zero in E:\wamp\www\resize_img\resize-class.php on line 182
    Call Stack
    # Time Memory Function Location
    1 0.0001 365664 {main}( ) ..\index.php:0
    2 0.0314 427856 resize->resizeImage( ) ..\index.php:10
    3 0.0314 427856 resize->getDimensions( ) ..\resize-class.php:69
    4 0.0314 427856 resize->getOptimalCrop( ) ..\resize-class.php:111

    ( ! ) Warning: Division by zero in E:\wamp\www\resize_img\resize-class.php on line 183
    Call Stack
    # Time Memory Function Location
    1 0.0001 365664 {main}( ) ..\index.php:0
    2 0.0314 427856 resize->resizeImage( ) ..\index.php:10
    3 0.0314 427856 resize->getDimensions( ) ..\resize-class.php:69
    4 0.0314 427856 resize->getOptimalCrop( ) ..\resize-class.php:111

    ( ! ) Warning: imagecreatetruecolor() [function.imagecreatetruecolor]: Invalid image dimensions in E:\wamp\www\resize_img\resize-class.php on line 76
    Call Stack
    # Time Memory Function Location
    1 0.0001 365664 {main}( ) ..\index.php:0
    2 0.0314 427856 resize->resizeImage( ) ..\index.php:10
    3 0.0316 428192 imagecreatetruecolor ( ) ..\resize-class.php:76

    ( ! ) Warning: imagecopyresampled() expects parameter 1 to be resource, boolean given in E:\wamp\www\resize_img\resize-class.php on line 77
    Call Stack
    # Time Memory Function Location
    1 0.0001 365664 {main}( ) ..\index.php:0
    2 0.0314 427856 resize->resizeImage( ) ..\index.php:10
    3 0.0317 428920 imagecopyresampled ( ) ..\resize-class.php:77

    ( ! ) Warning: imagecopyresampled() expects parameter 2 to be resource, boolean given in E:\wamp\www\resize_img\resize-class.php on line 201
    Call Stack
    # Time Memory Function Location
    1 0.0001 365664 {main}( ) ..\index.php:0
    2 0.0314 427856 resize->resizeImage( ) ..\index.php:10
    3 0.0318 428704 resize->crop( ) ..\resize-class.php:82
    4 0.0319 641104 imagecopyresampled ( ) ..\resize-class.php:201

    • andie

      @Jarrod
      You are the man! excellent stuff.

      @Harry

      I was getting similar errors to yours, it was working fine on my local computer, but as soon as I put it online it threw exceptions…

      Turns out I had a typo in a part of the class, which once corrected allowed the class to work properly.

    • http://www.lcbcchurch.com Nate Hamilton

      I’m having the same issues as you. Did you every figure out a fix to this issue?

  • Dakshina

    just 4 words

    clean, clear, super, easy

    Dakshina.

  • http://headwaythemes.com Chris Howard

    Great script! Have modified it to include vertical and horizontal crop alignment options.

  • http://newhind.com shakeel

    when i use the crop option then my image’s upper side cut.because u r croping it center . please tell me how to crop it from top.

  • http://www.milosmandic.com Milos

    Awesome! Thank´s for sharing! I have a improvement idea for all. If you add two more parameters to the cropfunction you can use this class with an imagecropper. Like Chris Howard did. In this case: $cropStartX and $cropStartY has to be dynamic.

  • http://ebookhorn.com batjoker

    Awesome! save some time in resizing my ebook thumbnails ;)

  • http://delicious.com/drwitt drwitt

    And there was much rejoicing!
    Thank you very much for this great article. Your class surely is one of the most elegant and up-to-date solutions I have seen so far (and there are a lot approaches out there, most of them bloated and oldfashioned crap). (Yay!)

  • http://what.ilike.lv fixed

    Nice script … I allready tought that I need to make one by my own, but this rocks … =]

  • LeNche

    You are the best :) Yesterday, I spend whole day to set different functions for resize images like Zend_View_Helper, and finally I did it. Thank you a lot. All the best…

  • Konrad

    Hey i had a probelm with openImage function but afeter i change it to my code it work great.

    below is my code:

    private function openImage($file)
    {
    $image_info = getimagesize($file);
    $this->image_type = $image_info[2];
    if( $this->image_type == IMAGETYPE_JPEG ) {
    $img = imagecreatefromjpeg($file);
    } elseif( $this->image_type == IMAGETYPE_GIF ) {
    $img = imagecreatefromgif($file);
    } elseif( $this->image_type == IMAGETYPE_PNG ) {
    $img = imagecreatefrompng($file);
    }
    return $img;
    }

    • Lopian Flora

      Thank you so much, it worked out great with your code, but I wanna know if there’s a way to make the background of the png file transparent instead of black.

  • Manga

    The auto with the square image, don’t crop with the small size.

  • http://N/a Jean Paul

    Well done for this tutorial it’s really what I was looking for, I am a beginner in PHP in need to get the image that the customer uploaded and then inserting that in the database how shell I do that please?

    Thanks in advance

  • http://www.colombiascortvip.com David

    This script was perfet for my website the only problem I had was with overwrite this script creates a new imagen but it wont over write so I did this small solution.

    // resize thumb start
    $filename=my_sample_pic.jpg

    $resizeObj = new resize(‘$filename’);
    $resizeObj -> resizeImage(213, 322, ‘exact’);
    $resizeObj -> saveImage(‘temp_$filename’, 100);

    //rename to overwrite original file
    rename(“temp_$filename”, “$filename”);

    // resize thumb end

  • junglbug

    Its is not re sizing images of 4000 X 3000 how to make that resize HD and FULL HD images ?

  • http://www.hitbiz.net Haider Abbas

    Hi Guys,

    I have implemented all the changes recommended by the users via the comments. Please note that Gabreil’s code must be included in the CLASS to prevent errors as I was getting errors before implementing the code mentioned by Gabriel.

    Here is the updated code with all required changes to make it work okay:

    resizeImage(150, 100, 0);
    # $resizeObj -> saveImage(‘images/cars/large/output.jpg’, 100);
    #
    #
    # ========================================================================#

    Class resize
    {
    // *** Class variables
    private $image;
    private $width;
    private $height;
    private $imageResized;

    function __construct($fileName)
    {
    // *** Open up the file
    $this->image = $this->openImage($fileName);

    // *** Get width and height
    $this->width = imagesx($this->image);
    $this->height = imagesy($this->image);
    }

    ## ——————————————————–

    private function openImage($file)
    {
    // Image info
    $info = getimagesize($file);
    if ($this->info) {
    switch ($this->info[2]) {
    case IMAGETYPE_PNG:
    return imagecreatefrompng($image);
    case IMAGETYPE_JPEG:
    return imagecreatefromjpeg($image);
    case IMAGETYPE_GIF:
    return imagecreatefromgif($image);
    }
    }
    return false;
    }

    ## ——————————————————–

    public function resizeImage($newWidth, $newHeight, $option=”auto”)
    {
    // *** Get optimal width and height – based on $option
    $optionArray = $this->getDimensions($newWidth, $newHeight, $option);

    $optimalWidth = $optionArray['optimalWidth'];
    $optimalHeight = $optionArray['optimalHeight'];

    // *** Resample – create image canvas of x, y size
    $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);

    ########## HA A USER SUGGESTED CODE TO PRESERVE TRANSPARENT IMAGES IN PNG
    // *** Resample – create image canvas of x, y size
    if (imagetypes() & IMG_PNG) {
    imagesavealpha($this->imageResized, true);
    imagealphablending($this->imageResized, false);
    }
    ##########

    imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);

    // *** if option is ‘crop’, then crop too
    if ($option == ‘crop’) {
    $this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
    }
    }

    ## ——————————————————–

    private function getDimensions($newWidth, $newHeight, $option)
    {

    switch ($option)
    {
    case ‘exact’:
    $optimalWidth = $newWidth;
    $optimalHeight= $newHeight;
    break;
    case ‘portrait’:
    $optimalWidth = $this->getSizeByFixedHeight($newHeight);
    $optimalHeight= $newHeight;
    break;
    case ‘landscape’:
    $optimalWidth = $newWidth;
    $optimalHeight= $this->getSizeByFixedWidth($newWidth);
    break;
    case ‘auto’:
    $optionArray = $this->getSizeByAuto($newWidth, $newHeight);
    $optimalWidth = $optionArray['optimalWidth'];
    $optimalHeight = $optionArray['optimalHeight'];
    break;
    case ‘crop’:
    $optionArray = $this->getOptimalCrop($newWidth, $newHeight);
    $optimalWidth = $optionArray['optimalWidth'];
    $optimalHeight = $optionArray['optimalHeight'];
    break;
    }
    return array(‘optimalWidth’ => $optimalWidth, ‘optimalHeight’ => $optimalHeight);
    }

    ## ——————————————————–

    private function getSizeByFixedHeight($newHeight)
    {
    $ratio = $this->width / $this->height;
    $newWidth = $newHeight * $ratio;
    return $newWidth;
    }

    private function getSizeByFixedWidth($newWidth)
    {
    $ratio = $this->height / $this->width;
    $newHeight = $newWidth * $ratio;
    return $newHeight;
    }

    private function getSizeByAuto($newWidth, $newHeight)
    {
    if ($this->height width)
    // *** Image to be resized is wider (landscape)
    {
    $optimalWidth = $newWidth;
    $optimalHeight= $this->getSizeByFixedWidth($newWidth);
    }
    elseif ($this->height > $this->width)
    // *** Image to be resized is taller (portrait)
    {
    $optimalWidth = $this->getSizeByFixedHeight($newHeight);
    $optimalHeight= $newHeight;
    }
    else
    // *** Image to be resizerd is a square
    {
    if ($newHeight getSizeByFixedWidth($newWidth);
    } else if ($newHeight > $newWidth) {
    $optimalWidth = $this->getSizeByFixedHeight($newHeight);
    $optimalHeight= $newHeight;
    } else {
    // *** Sqaure being resized to a square
    $optimalWidth = $newWidth;
    $optimalHeight= $newHeight;
    }
    }

    return array(‘optimalWidth’ => $optimalWidth, ‘optimalHeight’ => $optimalHeight);
    }

    ## ——————————————————–

    private function getOptimalCrop($newWidth, $newHeight)
    {

    $heightRatio = $this->height / $newHeight;
    $widthRatio = $this->width / $newWidth;

    if ($heightRatio height / $optimalRatio;
    $optimalWidth = $this->width / $optimalRatio;

    return array(‘optimalWidth’ => $optimalWidth, ‘optimalHeight’ => $optimalHeight);
    }

    ## ——————————————————–

    private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
    {
    // *** Find center – this will be used for the crop
    $cropStartX = ( $optimalWidth / 2) – ( $newWidth /2 );
    $cropStartY = ( $optimalHeight/ 2) – ( $newHeight/2 );

    $crop = $this->imageResized;
    //imagedestroy($this->imageResized);

    // *** Now crop from center to exact requested size
    $this->imageResized = imagecreatetruecolor($newWidth , $newHeight);
    imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
    }

    ## ——————————————————–

    public function saveImage($savePath, $imageQuality=”100″)
    {
    // *** Get extension
    $extension = strrchr($savePath, ‘.’);
    $extension = strtolower($extension);

    switch($extension)
    {
    case ‘.jpg’:
    case ‘.jpeg’:
    if (imagetypes() & IMG_JPG) {
    imagejpeg($this->imageResized, $savePath, $imageQuality);
    }
    break;

    case ‘.gif’:
    if (imagetypes() & IMG_GIF) {
    imagegif($this->imageResized, $savePath);
    }
    break;

    case ‘.png’:
    // *** Scale quality from 0-100 to 0-9
    $scaleQuality = round(($imageQuality/100) * 9);

    // *** Invert quality setting as 0 is best, not 9
    $invertScaleQuality = 9 – $scaleQuality;

    if (imagetypes() & IMG_PNG) {
    imagepng($this->imageResized, $savePath, $invertScaleQuality);
    }
    break;

    // … etc

    default:
    // *** No extension – No save.
    break;
    }

    imagedestroy($this->imageResized);
    }

    ## ——————————————————–

    }
    ?>

    I hope this will be helpful to all of you.

    I am using this class to resize all the images (JPG, PNG, GIF) in a folder on a Cpanel website. It works great. THANKS A LOT TO ORIGINAL AUTHOR AND GABRIEL.

  • JCalero

    Thanks Haider Abbas and the other mans.

    I have a problem, you have any solution???

    imagesx() expects parameter 1 to be resource, boolean given on line 40
    imagesy() expects parameter 1 to be resource, boolean given on line 41
    imagecopyresampled() expects parameter 2 to be resource

    and my new images are black

    any solution please??

  • Salih

    Hello,

    Thanks for the tutorial. It’s been really helpful. I wonder, if you have a similar tutorial for resizing videos? Is there a way to resize the videos during uploading with php?

    Thank you

  • Gökhan

    Very usefull. thanks