DISCLAIMER: This requires WordPress 3.4 to work correctly. The filter was added based on Trac Ticket #15989
Okay, to start, here is the function that we’re going to be working with, from ~/wp-includes/media.php :
/** * Retrieve calculated resized dimensions for use in imagecopyresampled(). * * Calculate dimensions and coordinates for a resized image that fits within a * specified width and height. If $crop is true, the largest matching central * portion of the image will be cropped out and resized to the required size. * * @since 2.5.0 * @uses apply_filters() Calls 'image_resize_dimensions' on $orig_w, $orig_h, $dest_w, $dest_h and * $crop to provide custom resize dimensions. * * @param int $orig_w Original width. * @param int $orig_h Original height. * @param int $dest_w New width. * @param int $dest_h New height. * @param bool $crop Optional, default is false. Whether to crop image or resize. * @return bool|array False on failure. Returned array matches parameters for imagecopyresampled() PHP function. */ function image_resize_dimensions($orig_w, $orig_h, $dest_w, $dest_h, $crop = false) { if ($orig_w <= 0 || $orig_h <= 0) return false; // at least one of dest_w or dest_h must be specific if ($dest_w <= 0 && $dest_h = $orig_w && $new_h >= $orig_h ) return false; // the return array matches the parameters to imagecopyresampled() // int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h return array( 0, 0, (int) $s_x, (int) $s_y, (int) $new_w, (int) $new_h, (int) $crop_w, (int) $crop_h ); }
Some people have looked at this and felt that there was no way to override the $s_y = floor( ($orig_h - $crop_h) / 2 );
line without hacking core. Well, that’s iffy, but if you scroll up above, you’ll see something that lets you basically ‘short-circuit’ the function in question:
// plugins can use this to provide custom resize dimensions $output = apply_filters( 'image_resize_dimensions', null, $orig_w, $orig_h, $dest_w, $dest_h, $crop ); if ( null !== $output ) return $output;
So here’s our function to make all crops start at (0,0) — customize it as you like:
function my_awesome_image_resize_dimensions( $payload, $orig_w, $orig_h, $dest_w, $dest_h, $crop ){ // Change this to a conditional that decides whether you // want to override the defaults for this image or not. if( false ) return $payload; if ( $crop ) { // crop the largest possible portion of the original image that we can size to $dest_w x $dest_h $aspect_ratio = $orig_w / $orig_h; $new_w = min($dest_w, $orig_w); $new_h = min($dest_h, $orig_h); if ( !$new_w ) { $new_w = intval($new_h * $aspect_ratio); } if ( !$new_h ) { $new_h = intval($new_w / $aspect_ratio); } $size_ratio = max($new_w / $orig_w, $new_h / $orig_h); $crop_w = round($new_w / $size_ratio); $crop_h = round($new_h / $size_ratio); $s_x = 0; // [[ formerly ]] ==> floor( ($orig_w - $crop_w) / 2 ); $s_y = 0; // [[ formerly ]] ==> floor( ($orig_h - $crop_h) / 2 ); } else { // don't crop, just resize using $dest_w x $dest_h as a maximum bounding box $crop_w = $orig_w; $crop_h = $orig_h; $s_x = 0; $s_y = 0; list( $new_w, $new_h ) = wp_constrain_dimensions( $orig_w, $orig_h, $dest_w, $dest_h ); } // if the resulting image would be the same size or larger we don't want to resize it if ( $new_w >= $orig_w && $new_h >= $orig_h ) return false; // the return array matches the parameters to imagecopyresampled() // int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h return array( 0, 0, (int) $s_x, (int) $s_y, (int) $new_w, (int) $new_h, (int) $crop_w, (int) $crop_h ); } add_filter( 'image_resize_dimensions', 'my_awesome_image_resize_dimensions', 10, 6 );
Hi George,
I’ve been banging my head against the wall all day on this. I’m using Elegant Themes’ SimplePress theme (http://www.elegantthemes.com/demo/?theme=SimplePress), and the homepage uses 4 sliders with thumbnails below. I only want to change the crop location for one photo (the 4th of the 4). I’m not a professional coder (although I can follow simple coding directions). However, your post above lost me at the final screenshot. Any pointers, suggestions or guidance you can provide?
Many thanks,
Diane
Ah, there’s the rub.
This is meant to change the crop location for ALL crops, not just one. The Attachment ID or file name isn’t passed in directly to the function, so there’s no way to switch based on that.
Is it possible to simply manually crop the one for that slide down to size, as it’s not a ‘policy’ of cropping you’re looking to implement, just a one-off?
Thanks for responding, George. Are you asking if it’s possible to crop (or in this case, re-crop) the original photo? If so, the answer is, sadly, no. I need to use a very horizontal photo–954x375px–and the image I want to use is almost square… not as horizontal as I need. I finally cropped the living daylights out of it to get to look great in the slider, and then the thumbnail issue reared its ugly head. I tried cropping the thumbnail in WordPress, but that doesn’t seem to affect the thumbnail that’s being pulled in below the slider. Ugh. I’m so frustrated!
The theme may actually be manually calling in tim-thumb or something to generate the thumbnail, rather than the internal WP mechanism.
P.S. And the other thumbnails would be thrown off-kilter if I changed the cropping location for them.
Have you tried manually re-cropping the image to the size you want and FTP’ing it up to replace the generated one in WordPress? WP doesn’t make it on the fly, so as long as you don’t regenerate thumbnails, you should be fine.
Ok so what if i just want the top to be fixed and crop from bottom or sides? any simple code to do this that i can insert in function.php
This was really helpful George. I looked for something like this a few months ago and there were no suggestions out there. Thanks so much 🙂
Yup! Although, to be fair, a couple months ago this filter wasn’t there, so it wouldn’t have been possible. 🙂
WOW thank you!
Thanks so much! Your code plus the Regenerate Thumbnails plugin is a great solution 🙂
Hi George,
i have been waiting for something like this so thank you very much. However when ever i use “regen. thumbnails” all the images fail and are listed as “undefined”. Any theories on this ? Thank you.
No idea.
Hi George,
Many thanks for this. Is there any way you can instruct an intermediate user on how to implement this? Where should this code be used? Sorry for the bother but you’re the only source I’ve found to solve this critical problem without hacking the core and I’d really love to benefit from your hard work!
Thanks,
NR
It’ll probably be best to put directly in your theme’s functions.php file. If you have a dev environment, tinker around until you get it right. Otherwise … set up a dev environment, then tinker?
The plugin Thumbnail Crop Position, http://wordpress.org/extend/plugins/thumbnail-crop-position/ alllows you to select the crop position of your thumbnails
Does that crop work for the initial upload only, or will it stick even if I regenerate the image thumbnails at a later time via something like http://wordpress.org/extend/plugins/regenerate-thumbnails/ ?
important question, im testing it right now.
Result: The crop via the “thumbnail crop position” plugin works even at a later time. (i.e. regenerate thumbnails plugin)
Hi, please help me! I dont know what I should to do to fix my thumbnail problem. dollsdreams.ru – all thumbnails cropped by the middle and doll`s heads are shrinks. I tried to follow your advice, but it does not helped to me. (sorry for my english)
Hi, Alexander!
You’re probably need to find someone to hire on for a quick bit of coding to get it up and running if it’s beyond you. I’d suggest a posting on http://jobs.wordpress.net/ personally.
Thank you! I have been looking for a way to do this without hacking the core.
Will have to try this. Am wondering though: any word on when a patch for this is going to get rolled into core (3.6 maybe 😀 ?)
This really isn’t something for core at all. It’s how to individually override the crop position if you need to, but the vast majority of users won’t. 🙂
Ah…every other similar posting I’ve read about this issue seemed to expect a core update to make to so photos cropped from X:0/Y:0 by default. Admittedly, some of them were…elderly. Thanks for the reply.
No worries! I know there are some plugins that can do it, and core can already let folks do custom crops of individual media files through its ui.
Thanks! 🙂
Hi, it’s very simple and works from version 3.51. In each image processing, a clipping with the mouse to select. This selection can then be applied alone on the thumbnail. Thus, the cut is determined.
Hallo, es ist ganz einfach und funktioniert ab Version 3.51. In der einzelnen Bildbearbeitung kann ein Ausschnitt mit der Maus gewählt werden. Diese Auswahl kann dann nur allein auf das Vorschaubild angewendet werden. Somit wird der Ausschnitt festgelegt.
Yes, but that’s for manually doing every single image, and if you regenerate your thumbnails, I believe they get wiped.
Totally legitimate to use, but a slightly different use case. 🙂
Plugin Thumbnail Crop Position
Ok. Für diese Aufgabe gibt es ein sehr gutes Plugin – hier
http://wordpress.org/plugins/thumbnail-crop-position/
Es ermöglicht bereits beim Hochladen der Bilder die Selektion des Ausschnittes 🙂
Okay. For this task, there is a very good plugin – here
http://wordpress.org/plugins/thumbnail-crop-position/
It already allows uploading of images, the selection of the cut 🙂
Best regards
Thank for the post. Saved me some time.
Hi I have used a plugin reg . Thumbnail who cropped all images due to which ugly thumbnails are displaying ,please tell how I can show original images in small size in thumbnails ??
hi George,
thanks for the code, I have reinstall my theme folder and lost the latest version of my function.php
tried to reinstall it be doesn t work anymore
to crop from top
what do i need to change in ur code? I can t remember if i had to change something and second question it is in theme function.php, correct?
You’d be better off putting it in a plugin, as opposed to a theme. The code is about the same, and it would pull across if you change themes later.
it didn t work for me
I pasted your code at bottom of theme/function.php
is that correct?
Reblogged this on Red-Headed Mule.
Hi George,
I’ve added the new function above to my theme function. Is that all or should I call the my_awesome_image_resize_dimensions function with the params?
Please help,
Thanks.
What areas of your code would you need to change to make the crop start at a different location, like (0,100) for example…?
…And, is it possible to assign this function to only selected thumbnail sizes (medium, large, etc.) and not to others…?
Thank you so much!
Finally a filter was added into core, I wasn’t aware! Thanks for the heads up 😉