WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a series of posts, all with featured images, but I need to be able to customise the crop top right corner. In this instance, I need them to be cropped from top right, but it would be useful to also know how to position that point myself.

At present, the add_image_size() function is taking its crop from the centre of the image. Not always pretty!!

share|improve this question
up vote 13 down vote accepted

Intermediate image generation is extremely rigid. image_resize() keeps it close to code and completely lacks hooks.

Pretty much only option for this is to hook into wp_generate_attachment_metadata and overwrite WP-generated image with your own (which will need bit of a image_resize() fork).

I need this for work so I might be able to share some code later.

Ok, here is rough, but working example. Note that setting up crop in this way requires understanding of imagecopyresampled().

add_filter('wp_generate_attachment_metadata', 'custom_crop');

function custom_crop($metadata) {

    $uploads = wp_upload_dir();
    $file = path_join( $uploads['basedir'], $metadata['file'] ); // original image file
    list( $year, $month ) = explode( '/', $metadata['file'] );
    $target = path_join( $uploads['basedir'], "{$year}/{$month}/".$metadata['sizes']['medium']['file'] ); // intermediate size file
    $image = imagecreatefromjpeg($file); // original image resource
    $image_target = wp_imagecreatetruecolor( 44, 44 ); // blank image to fill
    imagecopyresampled($image_target, $image, 0, 0, 25, 15, 44, 44, 170, 170); // crop original
    imagejpeg($image_target, $target, apply_filters( 'jpeg_quality', 90, 'image_resize' )); // write cropped to file

    return $metadata;
}
share|improve this answer
1  
sounds a lot like messing with the core!! – Mild Fuzz Jun 24 '11 at 9:35
5  
No, messing with the core would be changing the image_resize function. Rarst was making the point that you'd have to hook into the resizing process, but create the image sizes yourself manually. – TheDeadMedic Jun 24 '11 at 10:02
    
May I ask if this still works? I just implemented the hook into my functions.php file and I have add_image_size() functions set-up, but the cropped images still get cropped form the center out. – cr0z3r Dec 9 '11 at 22:40
    
@cr0z3r I know of no reason why it won't work. But note that this is only rough proof-of-concept example, rather than meaningful reliable code. – Rarst Dec 10 '11 at 13:50
    
Hm, strangely enough, it does not work on my theme - could it be because I was running locally (I highly doubt it)? I will have it up online and show it to you soon. – cr0z3r Dec 15 '11 at 16:32

I have developed a solution to this problem that does not require hacking the core: http://bradt.ca/archives/image-crop-position-in-wordpress/

I have also submitted a patch to core: http://core.trac.wordpress.org/ticket/19393

Add yourself as a Cc on the ticket to show your support for it to be added to core.

share|improve this answer
2  
@Rarst’s solution doesn’t change core files too. ;) – toscho Feb 19 '12 at 15:25
1  
@toscho I guess he didn't mean that the other answer changes core code. – kaiser Feb 20 '12 at 15:16

Wordpress codex has the answer, its below.

Set the image size by cropping the image and defining a crop position:

add_image_size( 'custom-size', 220, 220, array( 'left', 'top' ) ); // Hard crop left top

When setting a crop position, the first value in the array is the x axis crop position, the second is the y axis crop position.

x_crop_position accepts 'left' 'center', or 'right'. y_crop_position accepts 'top', 'center', or 'bottom'. By default, these values default to 'center' when using hard crop mode.

And also codex references a page which shows how crop positions acts.

http://havecamerawilltravel.com/photographer/wordpress-thumbnail-crop

share|improve this answer
    
This is awesome, should be the accepted answer, I think! – Dalton Nov 8 '15 at 20:57

You can use the plugin Thumbnail Crop Position to select the crop position of your thumbnails.

share|improve this answer

Alternative solution here: http://pixert.com/blog/cropping-post-featured-thumbnails-from-top-instead-of-center-in-wordpress-with-native-cropping-tool/

Just add this code to functions.php, then use "Regenerate Thumbnails" plugin (https://wordpress.org/plugins/regenerate-thumbnails/):

function px_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', 'px_image_resize_dimensions', 10, 6 );
share|improve this answer
    
Hi Niente0, welcome to WPSE and thank you for your answer. Would you mind editing your post to explain what your code does? Posts on StackExchange sites should explain their solution, and only include offsite links as references, not as entire solutions. Thanks again! – Tim Malone Apr 27 at 9:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.