Image Resize, Crop, Thumbnail, Watermark PHP Script

By David Zimmerman, aka Zim Zala Bim PHP

Just looking for some code to copy and paste instead of building the image resize, crop, thumbnail, watermark PHP script step-by-step? Click here.

In this post, we’re going to create a php function that helps process images. This could be used as part of a bigger application, or used in a plugin or module for a content management system. Most modern web-facing platforms are going to provide some form of this functionality already.

In this function, we will provide arguments to allow customization to the rendered image’s width and height, and whether or not to apply a watermark the image.

It should go without saying, but this code is only going to work if you have php and GD installed on your system.

And finally, here is all of the code in one piece:

<?php
function image_handler($source_image,$destination,$tn_w = 100,$tn_h = 100,$quality = 80,$wmsource = false) {

  // The getimagesize functions provides an "imagetype" string contstant, which can be passed to the image_type_to_mime_type function for the corresponding mime type
  $info = getimagesize($source_image);
  $imgtype = image_type_to_mime_type($info[2]);

  // Then the mime type can be used to call the correct function to generate an image resource from the provided image
  switch ($imgtype) {
  case 'image/jpeg':
  	$source = imagecreatefromjpeg($source_image);
  	break;
  case 'image/gif':
  	$source = imagecreatefromgif($source_image);
  	break;
  case 'image/png':
  	$source = imagecreatefrompng($source_image);
  	break;
  default:
  	die('Invalid image type.');
  }

  // Now, we can determine the dimensions of the provided image, and calculate the width/height ratio
  $src_w = imagesx($source);
  $src_h = imagesy($source);
  $src_ratio = $src_w/$src_h;

  // Now we can use the power of math to determine whether the image needs to be cropped to fit the new dimensions, and if so then whether it should be cropped vertically or horizontally. We're just going to crop from the center to keep this simple.
  if ($tn_w/$tn_h > $src_ratio) {
  $new_h = $tn_w/$src_ratio;
  $new_w = $tn_w;
  } else {
  $new_w = $tn_h*$src_ratio;
  $new_h = $tn_h;
  }
  $x_mid = $new_w/2;
  $y_mid = $new_h/2;

  // Now actually apply the crop and resize!
  $newpic = imagecreatetruecolor(round($new_w), round($new_h));
  imagecopyresampled($newpic, $source, 0, 0, 0, 0, $new_w, $new_h, $src_w, $src_h);
  $final = imagecreatetruecolor($tn_w, $tn_h);
  imagecopyresampled($final, $newpic, 0, 0, ($x_mid-($tn_w/2)), ($y_mid-($tn_h/2)), $tn_w, $tn_h, $tn_w, $tn_h);

  // If a watermark source file is specified, get the information about the watermark as well. This is the same thing we did above for the source image.
  if($wmsource) {
  $info = getimagesize($wmsource);
  $imgtype = image_type_to_mime_type($info[2]);
  switch ($imgtype) {
  	case 'image/jpeg':
    	$watermark = imagecreatefromjpeg($wmsource);
    	break;
  	case 'image/gif':
    	$watermark = imagecreatefromgif($wmsource);
    	break;
  	case 'image/png':
    	$watermark = imagecreatefrompng($wmsource);
    	break;
  	default:
    	die('Invalid watermark type.');
  }

  // Determine the size of the watermark, because we're going to specify the placement from the top left corner of the watermark image, so the width and height of the watermark matter.
  $wm_w = imagesx($watermark);
  $wm_h = imagesy($watermark);

  // Now, figure out the values to place the watermark in the bottom right hand corner. You could set one or both of the variables to "0" to watermark the opposite corners, or do your own math to put it somewhere else.
  $wm_x = $tn_w - $wm_w;
  $wm_y = $tn_h - $wm_h;

  // Copy the watermark onto the original image
  // The last 4 arguments just mean to copy the entire watermark
  imagecopy($final, $watermark, $wm_x, $wm_y, 0, 0, $tn_w, $tn_h);
  }

  // Ok, save the output as a jpeg, to the specified destination path at the desired quality.
  // You could use imagepng or imagegif here if you wanted to output those file types instead.
  if(Imagejpeg($final,$destination,$quality)) {
  return true;
  }

  // If something went wrong
  return false;

}
?>

<!-- Add a little image upload form -->
<form method="post" enctype="multipart/form-data">
Source Image: <input type="file" name="uploaded_image" />
<input type="submit" value="Handle This Image" />
</form>

<?php
//Process the form submission
if($_FILES) {
  //get the uploaded image
  $source_image = $_FILES['uploaded_image']['tmp_name'];

  //specify the output path in your file system and the image size/quality
  $destination = '/path/to/the/final/image/filename.jpg';
  $tn_w = 400;
  $tn_h = 400;
  $quality = 100;

  //path to an optional watermark
  $wmsource = '/path/to/your/watermark/image.png';

  // Try to process the image and echo a small message whether or not it worked. If the image is saved somewhere public, you could add an <img src> tag to display the image here, too!
  $success = image_handler($source_image,$destination,$tn_w,$tn_h,$quality,$wmsource);
  if($success) { echo "Your image was saved successfully!"; }
  else { echo "Your image was not saved."; }
}

?>

And that’s it!

Have any questions or find this image resize, thumbnail, watermark PHP script useful? Then make sure to leave a comment below and share this post!

 

View Comments

26 responses to “Image Resize, Crop, Thumbnail, Watermark PHP Script”

  1. how can i change the watermark padding? would like to put in x=3 and y=34 from the top left corner.. 🙂

    • In the image_handler function, change this part (under the comment starting “if we’re adding a watermark”):

          imagecopy($final, $watermark, $tn_w - $wm_w, $tn_h - $wm_h, 0, 0, $tn_w, $tn_h);
      

      To this:

         $x_pos = 3;
         $y_pos = 34;
         imagecopy($final, $watermark, $x_pos, $y_pos, 0, 0, $tn_w, $tn_h);
      

      Check out php.net’s entry on imagecopy if you’d like to understand more.

    • The script only works for gifs, pngs, and jpegs, that error happens when you’re using a different type of image, or if the mime type is reported incorrectly.

      Also, it should go without saying but make sure you have GD installed!

  2. Hi,

    I am trying to figure out a way to resize (not crop) the image so that the watermark will allaways be 25% in the lower right corner.
    I love your script, and it works fine, but it crops the images so that it is partly gone (especially with a rectangular shape as image and a square as watermark)

    Can you help me out please
    Thanks
    max

  3. I figured it out, thanks anyway:
    $wm_w = ceil($new_w/2);
    $wm_h = ceil($wm_w/imagesx($watermark)*imagesy($watermark));
    imagecopyresized($final, $watermark, $tn_w – $wm_w, $tn_h – $wm_h, 0, 0, $wm_w ,$wm_h, imagesx($watermark), imagesy($watermark));

  4. Great script, thanks.
    I want to use this script not for the thumbnail but for the main image and I don’t want to crop the main image, only resize the main image. I am trying to change or leave out the crop part but not with a desired result. Can you tell me what to do to let the script only resizing?
    Thanks

    • Is GD installed? Is the destination path writeable? That error is specified in the code if the image handler fails, and those are the two most likely reasons.

    • The placement of the watermark can be calculated as half the width of the big image, minus half the width of the watermark being the left offset, and similarly for the height for the top offset.

  5. Hi, I have and image 4000 x 4000 pixels and want to crop to 1920 x 1080 starting at x = 600px and Y = 1400px. Let’s say the source name is original.jpg and the final is cropped.jpg.
    Can someone tell me the parameters I should change? and where are they?

    Thank you a lot

    Julio

  6. Hello,
    I always have the same message:
    Warning: getimagesize(img/): failed to open stream: No such file or directory in C:\wamp\www\intro-js\crop5\index.php on line 48
    Invalid watermark type.
    and the picture is not uploaded 🙁
    How can i to fix it?
    Thanks for answer…
    Fabrice

    • Hi Fabrice, it sounds like you’re passing an argument for a watermark but aren’t giving it the proper path to a watermark image. If you don’t want the watermark, with this example you’d set $wmsource to false before the call to image_handler(). If you do, make sure you’re specifying a valid local path to an image.

  7. Nice post!

    It’s both clear and complete, perfect to understand how PHP handles images.
    I needed an example to link to in my last blog post and this is exactly what I was looking for.
    Thanks 🙂

  8. Is this code considered “safe” or “secure” as is or is this just for the image sizing etc. and security needs to be implemented by other means?

    Thanks in advance.

  9. Hey Juan, this is just an image resizing script, it is not safe as is and user input is not validated. You would need to provide security separately.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Are You Ready To Do More with Mind?

Click the link below to get started!

Work With Mind