Image Resize, Crop, Thumbnail, Watermark PHP Script

by Zim Zala Bim on Tuesday, August 3, 2010

Blog? I’m not very good at blogging, how about I just write a little script here instead?

We’re going to write a function called image_handler in PHP. We’ll provide parameters to specify the image width, height, whether or not to watermark the image, and the source of the watermark, when the function is called. We’ll supply a few default values for these parameters as well.

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

  #find out what type of image this is
  $info = getimagesize($source_image);
  $imgtype = image_type_to_mime_type($info[2]);

  #assuming the mime type is correct
  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.');
  }

  #Figure out the dimensions of the image and the dimensions of the desired thumbnail
  $src_w = imagesx($source);
  $src_h = imagesy($source);
  $src_ratio = $src_w/$src_h;
  #Do some math to figure out which way we'll need to crop the image
  #to get it proportional to the new size, then crop or adjust as needed
  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;
  $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 we need to add a watermark
  if($wmsource) {
    #find out what type of image the watermark is
    $info = getimagesize($wmsource);
    $imgtype = image_type_to_mime_type($info[2]);

    #assuming the mime type is correct
    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.');
    }

    #if we're adding a watermark, figure out the size of the watermark
    #and then place the watermark image on the bottom right of the image
    $wm_w = imagesx($watermark);
    $wm_h = imagesy($watermark);
    imagecopy($final, $watermark, $tn_w - $wm_w, $tn_h - $wm_h, 0, 0, $tn_w, $tn_h);
  }
  if(Imagejpeg($final,$destination,$quality)) {
    return true;
  }
  return false;
}
?>

Now we’ll write a small form for uploading the images we want to handle with this function.

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

And finally, the uploaded image processing, setting parameters, and a small success/failure message. Make sure the destination path is writable!

if($_FILES) {
$source_image = $_FILES['uploaded_image']['tmp_name'];
$destination = '/path/to/the/final/image/filename.jpg';
$tn_w = 400;
$tn_h = 400;
$quality = 100;
$wmsource = '/path/to/your/watermark/image.png';
$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."; }
}
Zim Zala Bim AKA: David Zimmerman

Zim (aka David) is a web developer and co-founder of MIND. He does not write that often, and when he does, you'll be glad!

  • Network Switch

    I am really thankful to this topic because it really gives great information.

  • whocares

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

    • MIND

      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.

  • whocares

    thanks, working fine :)

  • Rafael Caro

    I’m getting the “Invalid image type.” error, any help?

    • MIND

      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!

  • Renae

    This is an incredible script. Thank you very much.

  • mbabarnasim

    thank u very much for this great post

  • http://www.webtales.org Max

    Script is wonderfull thanks!

  • max van straaten

    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

  • max van straaten

    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));

  • thikonit

    you re awesome man..

  • Robbie

    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

  • Ciro

    Thanks for share the code.