Resize and Crop to a specific width x height with a crop suggestion point.

I really don’t have a shorter description for this.  I was working on a personal project the other day and realized that this might be a nifty function.  Basically, you know all those snippets to make cropped thumbnails (squares and the like), and how most of them either center or crop to the top of an image.  I wanted a new function that would crop to most any size I desired and any position on the image I desired without the need to change any code, only parameters.  And thus img_resize_crop was born.

Function code is below, try out a demo at http://rrbits.com/resizer/ (Demo code is available here: http://rrbits.com/resizer.zip )

Right now it’s pure GD (uses a sharpening convolution matrix to get over GD’s resizing blurryness), though could probably be converted to ImageMagick by someone who knows more about ImageMagick than I.  (Plus more patience, no desire to port it right now.)

 $evil_threshold) $twidth = $evil_threshold;
   if($theight > $evil_threshold) $theight = $evil_threshold;
   

   /*  The ratio of the thumbnail and the ratio 
    of the original image.*/
   $t_ratio = $twidth / $theight;
   $o_ratio = imagesx($src) / imagesy($src);
   $new = imagecreatetruecolor($twidth, $theight);
   
   /*Ideally, we'll want to grab as much of 
     the source image as possible.
     
     So we need to figure out how much to grab based on 
     the ratios of the desired thumbnail and the original
     image.*/
   if($t_ratio > $o_ratio)
   {
      $i_width = imagesx($src);
      $i_height = floor($i_width / $t_ratio);
   }
   else
   {
      $i_height = imagesy($src);
      $i_width = floor($i_height * $t_ratio);
   }
   
   /*Calculate the upper-left corner of the 
     source image grab area.  These will be 
     adjusted differently based on the method selected.*/
   $s_x = $center_x - floor($i_width/2);
   $s_y = $center_y - floor($i_height/2);
   
  
   
   switch($method)
   {
      case 'onlycrop':  
         $i_width = (imagesx($src) > $twidth) ? $twidth : imagesx($src);
         $i_height = (imagesy($src) > $theight) ? $theight : imagesy($src);
         $s_x = $center_x - floor($i_width/2);
         $s_y = $center_y - floor($i_height/2);   

         /*Make sure we're inside the left and top boundaries.*/
         $s_x = ($s_x < 0) ? 0 : $s_x;
         $s_y = ($s_y < 0) ? 0 : $s_y;
         
         /*Make sure we're inside the bottom and right boundaries.*/
         $s_x = ($center_x + ceil($i_width/2) > imagesx($src)) ? imagesx($src) - $i_width : $s_x;
         $s_y = ($center_y + ceil($i_height/2) > imagesy($src)) ? imagesy($src) - $i_height : $s_y;  
         
         break;      
      default:
      case 'suggest':
         /*Condition: Crop is thinner (ratio-wise) than the original image.*/
         if($t_ratio <= $o_ratio)
         {
            $s_y = 0;
            $s_x = ($s_x < 0) ? 0 : $s_x;
            $s_x = ($center_x + ceil($i_width/2) > imagesx($src)) ? imagesx($src) - $i_width : $s_x;
         }
         else /*Condition: Crop is wider (ratio-wise) than the original image.*/
         {
            $s_x = 0;
            $s_y = ($s_y < 0) ? 0 : $s_y;
            $s_y = ($center_y + ceil($i_height/2) > imagesy($src)) ? imagesy($src) - $i_height : $s_y;   
         }
         break;
      case 'force':
         /*Condition: Crop is thinner (ratio-wise) than the original image.*/
         if($t_ratio <= $o_ratio)
         {
            /*Find the maximum possible height with the requested center_y.*/
            $i_height = ($center_y > floor(imagesy($src)/2)) ? (imagesy($src) - $center_y) * 2 : $center_y * 2;
            $i_width = floor($i_height * $t_ratio); /*Height for said width.*/
            
            /*If that puts the source box out of bounds, we'll need to proportionally scale down.*/
            if($center_x - floor($i_width/2) < 0 || $center_x + floor($i_width/2) > imagesx($src))
            {
               /*Minimum width.*/
               $i_width = ($center_x > floor(imagesx($src)/2)) ? (imagesx($src) - $center_x) * 2 : $center_x * 2;
               $i_height = floor($i_width / $t_ratio);
            }
            /*Recalculate source x and y*/
            $s_x = $center_x - floor($i_width/2);
            $s_y = $center_y - floor($i_height/2);            
         }
         else /*Condition: Crop is wider (ratio-wise) than the original image.*/
         {
            /*Find the maximum possible width with the requested center_x.*/
            $i_width = ($center_x > floor(imagesx($src)/2)) ? (imagesx($src) - $center_x) * 2 : $center_x * 2;
            $i_height = floor($i_width / $t_ratio); /*Height for said width.*/
            
            /*If that puts the source box out of bounds, we'll need to proportionally scale down.*/
            if($center_y - floor($i_height/2) < 0 || $center_y + floor($i_height/2) > imagesy($src))
            {
               /*Minimum height.*/
               $i_height = ($center_y > floor(imagesy($src)/2)) ? (imagesy($src) - $center_y) * 2 : $center_y * 2;
               $i_width = $i_height * $t_ratio;
            }
            /*Recalculate source x and y*/
            $s_x = $center_x - floor($i_width/2);
            $s_y = $center_y - floor($i_height/2);
         }
         
         break;
   }
   
   imagecopyresampled($new, $src, 
     /*Destination Coords*/
     0,0,
     /*Source Coords*/
     $s_x,$s_y,
     /*Destination Geometry*/
     $twidth, $theight,
     /*Source Geometry*/
     $i_width, $i_height
     );
   
   if($sharpen)
   {
      $sharpen_matrix = array(array(-1,-1,-1),array(-1,16,-1),array(-1,-1,-1));
      $divisor = 8;
      $offset = 0;

      imageconvolution($new, $sharpen_matrix, $divisor, $offset);
   }
   
   return $new;
}