{"id":190,"date":"2010-07-18T21:15:10","date_gmt":"2010-07-19T03:15:10","guid":{"rendered":"http:\/\/rrbits.com\/epb\/?p=190"},"modified":"2011-02-06T17:41:24","modified_gmt":"2011-02-06T23:41:24","slug":"resize-and-crop","status":"publish","type":"post","link":"https:\/\/rrbits.com\/epb\/2010\/07\/18\/resize-and-crop\/","title":{"rendered":"Resize and Crop to a specific width x height with a crop suggestion point."},"content":{"rendered":"<p>I really don&#8217;t have a shorter description for this.\u00a0 I was working on a personal project the other day and realized that this might be a nifty function.\u00a0 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.\u00a0 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.\u00a0 And thus img_resize_crop was born.<\/p>\n<p><!--more-->Function code is below, try out a demo at <a href=\"https:\/\/rrbits.com\/resizer\/\">https:\/\/rrbits.com\/resizer\/<\/a> (Demo code is available here: <a href=\"https:\/\/rrbits.com\/resizer.zip\">https:\/\/rrbits.com\/resizer.zip<\/a> )<\/p>\n<p>Right now it&#8217;s pure GD (uses a sharpening convolution matrix to get over GD&#8217;s resizing blurryness), though could probably be converted to ImageMagick by someone who knows more about ImageMagick than I.\u00a0 (Plus more patience, no desire to port it right now.)<\/p>\n<pre lang=\"php\"><?php\r\n\/**\r\n * img_resize_crop\r\n * Resizes an image to a specific size, cropping if necessary, allows center-weighting.\r\n *\r\n * @param Resource $src - GD Resource Image to use.\r\n * @param Integer $twidth - Thumbnail width\r\n * @param Integer $theight - Thumbnail height\r\n * @param Integer $center_x - The x value of the target center location, leaving it at -1 autocalculates. [Default: -1]\r\n * @param Integer $center_y - The y value of the target center location, leaving it at -1 autocalculates. [Default: -1]\r\n * @param String $method - Method to use for the resize.  [Default:suggest]\r\n *   'suggest' (provided center coordinate is only guaranteed to be in the picture.)\r\n *   'force' (The provided coordinate is forced into being the center, additional data is trimmed to ensure this.)\r\n *   'onlycrop' (Not sure why you would use this, but only performs cropping.)\r\n * @param Boolean $sharpen - Specify whether or not to sharpen the resultant thumbnail [Default:true]\r\n * @param Int $evil_threshold - Maximum thumbnail width\/height to prevent attempts at evil. [Default:1024]\r\n *\/\r\nfunction img_resize_crop($src, $twidth, $theight, $center_x = -1, \r\n    $center_y = -1, $method = 'suggest', $sharpen = true, $evil_threshold = 1024)\r\n{\r\n   \/*Set defaults if they are not provided.*\/\r\n   if($center_x == -1 || ($method == 'force' &#038;&#038; $center_x == 0))\r\n   {\r\n      $center_x = floor(imagesx($src)\/2);\r\n   }\r\n   \r\n   if($center_y == -1 || ($method == 'force' &#038;&#038; $center_y == 0))\r\n   {\r\n      $center_y = floor(imagesy($src)\/2);\r\n   }\r\n   \r\n   \/* Prevent evil *\/\r\n   if($twidth > $evil_threshold) $twidth = $evil_threshold;\r\n   if($theight > $evil_threshold) $theight = $evil_threshold;\r\n   \r\n\r\n   \/*  The ratio of the thumbnail and the ratio \r\n    of the original image.*\/\r\n   $t_ratio = $twidth \/ $theight;\r\n   $o_ratio = imagesx($src) \/ imagesy($src);\r\n   $new = imagecreatetruecolor($twidth, $theight);\r\n   \r\n   \/*Ideally, we'll want to grab as much of \r\n     the source image as possible.\r\n     \r\n     So we need to figure out how much to grab based on \r\n     the ratios of the desired thumbnail and the original\r\n     image.*\/\r\n   if($t_ratio > $o_ratio)\r\n   {\r\n      $i_width = imagesx($src);\r\n      $i_height = floor($i_width \/ $t_ratio);\r\n   }\r\n   else\r\n   {\r\n      $i_height = imagesy($src);\r\n      $i_width = floor($i_height * $t_ratio);\r\n   }\r\n   \r\n   \/*Calculate the upper-left corner of the \r\n     source image grab area.  These will be \r\n     adjusted differently based on the method selected.*\/\r\n   $s_x = $center_x - floor($i_width\/2);\r\n   $s_y = $center_y - floor($i_height\/2);\r\n   \r\n  \r\n   \r\n   switch($method)\r\n   {\r\n      case 'onlycrop':  \r\n         $i_width = (imagesx($src) > $twidth) ? $twidth : imagesx($src);\r\n         $i_height = (imagesy($src) > $theight) ? $theight : imagesy($src);\r\n         $s_x = $center_x - floor($i_width\/2);\r\n         $s_y = $center_y - floor($i_height\/2);   \r\n\r\n         \/*Make sure we're inside the left and top boundaries.*\/\r\n         $s_x = ($s_x < 0) ? 0 : $s_x;\r\n         $s_y = ($s_y < 0) ? 0 : $s_y;\r\n         \r\n         \/*Make sure we're inside the bottom and right boundaries.*\/\r\n         $s_x = ($center_x + ceil($i_width\/2) > imagesx($src)) ? imagesx($src) - $i_width : $s_x;\r\n         $s_y = ($center_y + ceil($i_height\/2) > imagesy($src)) ? imagesy($src) - $i_height : $s_y;  \r\n         \r\n         break;      \r\n      default:\r\n      case 'suggest':\r\n         \/*Condition: Crop is thinner (ratio-wise) than the original image.*\/\r\n         if($t_ratio <= $o_ratio)\r\n         {\r\n            $s_y = 0;\r\n            $s_x = ($s_x < 0) ? 0 : $s_x;\r\n            $s_x = ($center_x + ceil($i_width\/2) > imagesx($src)) ? imagesx($src) - $i_width : $s_x;\r\n         }\r\n         else \/*Condition: Crop is wider (ratio-wise) than the original image.*\/\r\n         {\r\n            $s_x = 0;\r\n            $s_y = ($s_y < 0) ? 0 : $s_y;\r\n            $s_y = ($center_y + ceil($i_height\/2) > imagesy($src)) ? imagesy($src) - $i_height : $s_y;   \r\n         }\r\n         break;\r\n      case 'force':\r\n         \/*Condition: Crop is thinner (ratio-wise) than the original image.*\/\r\n         if($t_ratio <= $o_ratio)\r\n         {\r\n            \/*Find the maximum possible height with the requested center_y.*\/\r\n            $i_height = ($center_y > floor(imagesy($src)\/2)) ? (imagesy($src) - $center_y) * 2 : $center_y * 2;\r\n            $i_width = floor($i_height * $t_ratio); \/*Height for said width.*\/\r\n            \r\n            \/*If that puts the source box out of bounds, we'll need to proportionally scale down.*\/\r\n            if($center_x - floor($i_width\/2) < 0 || $center_x + floor($i_width\/2) > imagesx($src))\r\n            {\r\n               \/*Minimum width.*\/\r\n               $i_width = ($center_x > floor(imagesx($src)\/2)) ? (imagesx($src) - $center_x) * 2 : $center_x * 2;\r\n               $i_height = floor($i_width \/ $t_ratio);\r\n            }\r\n            \/*Recalculate source x and y*\/\r\n            $s_x = $center_x - floor($i_width\/2);\r\n            $s_y = $center_y - floor($i_height\/2);            \r\n         }\r\n         else \/*Condition: Crop is wider (ratio-wise) than the original image.*\/\r\n         {\r\n            \/*Find the maximum possible width with the requested center_x.*\/\r\n            $i_width = ($center_x > floor(imagesx($src)\/2)) ? (imagesx($src) - $center_x) * 2 : $center_x * 2;\r\n            $i_height = floor($i_width \/ $t_ratio); \/*Height for said width.*\/\r\n            \r\n            \/*If that puts the source box out of bounds, we'll need to proportionally scale down.*\/\r\n            if($center_y - floor($i_height\/2) < 0 || $center_y + floor($i_height\/2) > imagesy($src))\r\n            {\r\n               \/*Minimum height.*\/\r\n               $i_height = ($center_y > floor(imagesy($src)\/2)) ? (imagesy($src) - $center_y) * 2 : $center_y * 2;\r\n               $i_width = $i_height * $t_ratio;\r\n            }\r\n            \/*Recalculate source x and y*\/\r\n            $s_x = $center_x - floor($i_width\/2);\r\n            $s_y = $center_y - floor($i_height\/2);\r\n         }\r\n         \r\n         break;\r\n   }\r\n   \r\n   imagecopyresampled($new, $src, \r\n     \/*Destination Coords*\/\r\n     0,0,\r\n     \/*Source Coords*\/\r\n     $s_x,$s_y,\r\n     \/*Destination Geometry*\/\r\n     $twidth, $theight,\r\n     \/*Source Geometry*\/\r\n     $i_width, $i_height\r\n     );\r\n   \r\n   if($sharpen)\r\n   {\r\n      $sharpen_matrix = array(array(-1,-1,-1),array(-1,16,-1),array(-1,-1,-1));\r\n      $divisor = 8;\r\n      $offset = 0;\r\n\r\n      imageconvolution($new, $sharpen_matrix, $divisor, $offset);\r\n   }\r\n   \r\n   return $new;\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I really don&#8217;t have a shorter description for this.\u00a0 I was working on a personal project the other day and realized that this might be a nifty function.\u00a0 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&#8230;  <a class=\"excerpt-read-more\" href=\"https:\/\/rrbits.com\/epb\/2010\/07\/18\/resize-and-crop\/\" title=\"ReadResize and Crop to a specific width x height with a crop suggestion point.\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[31],"tags":[3995,3994,4262],"class_list":["post-190","post","type-post","status-publish","format-standard","hentry","category-php","tag-gd","tag-images","tag-php"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/rrbits.com\/epb\/wp-json\/wp\/v2\/posts\/190","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rrbits.com\/epb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rrbits.com\/epb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rrbits.com\/epb\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rrbits.com\/epb\/wp-json\/wp\/v2\/comments?post=190"}],"version-history":[{"count":12,"href":"https:\/\/rrbits.com\/epb\/wp-json\/wp\/v2\/posts\/190\/revisions"}],"predecessor-version":[{"id":312,"href":"https:\/\/rrbits.com\/epb\/wp-json\/wp\/v2\/posts\/190\/revisions\/312"}],"wp:attachment":[{"href":"https:\/\/rrbits.com\/epb\/wp-json\/wp\/v2\/media?parent=190"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rrbits.com\/epb\/wp-json\/wp\/v2\/categories?post=190"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rrbits.com\/epb\/wp-json\/wp\/v2\/tags?post=190"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}