Random Renegade Bits
Just another Random Renegade Bits weblog
  • Home
  • Zombinanza!
  • Old Projects and Content
    • Old Wallpapers
Browse: Home / php / Resize and Crop to a specific width x height with a crop suggestion point.

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

By epb on July 18, 2010

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

<?php
/**
 * img_resize_crop
 * Resizes an image to a specific size, cropping if necessary, allows center-weighting.
 *
 * @param Resource $src - GD Resource Image to use.
 * @param Integer $twidth - Thumbnail width
 * @param Integer $theight - Thumbnail height
 * @param Integer $center_x - The x value of the target center location, leaving it at -1 autocalculates. [Default: -1]
 * @param Integer $center_y - The y value of the target center location, leaving it at -1 autocalculates. [Default: -1]
 * @param String $method - Method to use for the resize.  [Default:suggest]
 *   'suggest' (provided center coordinate is only guaranteed to be in the picture.)
 *   'force' (The provided coordinate is forced into being the center, additional data is trimmed to ensure this.)
 *   'onlycrop' (Not sure why you would use this, but only performs cropping.)
 * @param Boolean $sharpen - Specify whether or not to sharpen the resultant thumbnail [Default:true]
 * @param Int $evil_threshold - Maximum thumbnail width/height to prevent attempts at evil. [Default:1024]
 */
function img_resize_crop($src, $twidth, $theight, $center_x = -1, 
    $center_y = -1, $method = 'suggest', $sharpen = true, $evil_threshold = 1024)
{
   /*Set defaults if they are not provided.*/
   if($center_x == -1 || ($method == 'force' && $center_x == 0))
   {
      $center_x = floor(imagesx($src)/2);
   }
 
   if($center_y == -1 || ($method == 'force' && $center_y == 0))
   {
      $center_y = floor(imagesy($src)/2);
   }
 
   /* Prevent evil */
   if($twidth > $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;
}

No related posts.

Posted in php | Tagged gd, images, php

« Previous

Search

Archives

  • July 2010
  • June 2010
  • May 2010
  • March 2010
  • January 2010
  • December 2009
  • November 2009
  • October 2009
  • September 2009
  • August 2009
  • July 2009
  • June 2009
  • May 2009
  • February 2009
  • September 2008
  • August 2008
  • December 2007
  • August 2007

Tags

actionscript charity cloud code computer problems danbooru flash fuse game gd hard drive images Internet linux marisa metadata mounting mp3 music php pipes rambling rss screenshots search slightly random storage touhou ubuntu utility vhd web

Copyright © 2010 Random Renegade Bits.

Powered by WordPress and Hybrid.