How to change post thumbnail crop position in WordPress WITHOUT HACKING CORE

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

39 thoughts on “How to change post thumbnail crop position in WordPress WITHOUT HACKING CORE

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

  2. 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?

    1. 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!

  3. P.S. And the other thumbnails would be thrown off-kilter if I changed the cropping location for them.

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

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

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

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

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

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

    1. 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. 🙂

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

        1. 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! 🙂

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

    1. 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. 🙂

  9. 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 ??

  10. 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?

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

  12. What areas of your code would you need to change to make the crop start at a different location, like (0,100) for example…?

  13. …And, is it possible to assign this function to only selected thumbnail sizes (medium, large, etc.) and not to others…?

    Thank you so much!

Comments are closed.