WordPress.org

Ready to get started?Download WordPress

Forums

[hack] crop custom thumbnail sizes (19 posts)

  1. redannick
    Member
    Posted 3 years ago #

    I'm pretty new to wordpress but found a limitation that I needed to fix. I'm implementing custom image sizes using add_image_size() and wanted the editors to be able to crop these thumbnails themselves. I found the excellent crop tool in the back end but it only had options for "all image sizes", "thumbnail only" or "all except thumbnail" - no mention of my custom sizes.

    I've hacked the code to allow this and thought I'd post it in case it helps anyone and for anyone perhaps to advise me that a) I didn't need to do this b) I've done it badly/dangerously or c) I could do it better - perhaps with a plugin or something? I feel a little insecure with this hack and of course will have to reapply it whenever I update wp.

    Anyhow, here's the code:

    /wp-includes/media.php ~ Line 181
    adds option variables for the registered image size - to be accessed in image-edit.php

    /**
     * Registers a new image size
     */
    function add_image_size( $name, $width = 0, $height = 0, $crop = false ) {
    	global $_wp_additional_image_sizes;
    	$_wp_additional_image_sizes[$name] = array( 'width' => absint( $width ), 'height' => absint( $height ), 'crop' => (bool) $crop );
    	add_option($name."_size_w", $width);
    	add_option($name."_size_h", $height);
    	add_option($name."_crop", $crop);
    }

    /wp-admin/includes/image-edit.php ~ Line 179
    adds the options to the list of radio buttons in the interface

    <?php 
    
    function myfunction($value,$key,$pid)
    {
    	echo '<label class="imgedit-label">';
    	echo '<input type="radio" name="imgedit-target-'.$pid.'" value="'.$key.'" /> '.$key.'</label>';
    	// preview of image size
    	echo wp_get_attachment_image($pid, $key);
    }
    
    array_walk($meta['sizes'],"myfunction", $post_id);
    ?>

    /wp-admin/includes/image-edit.php ~ Line 613
    use the $meta['sizes'] array instead of hardcoded defaults and add catch all for the custom sizes to be added singly to the $sizes array that will be used to apply the manipulation.

    if ( $success && ('nothumb' == $target || 'all' == $target) ) {
    			$sizes = apply_filters( 'intermediate_image_sizes', array_keys($meta['sizes']) );
    			if ( 'nothumb' == $target )
    				$sizes = array_diff( $sizes, array('thumbnail') );
    		}
    
    		$return->fw = $meta['width'];
    		$return->fh = $meta['height'];
    	} elseif ( 'thumbnail' == $target ) {
    		$sizes = array( 'thumbnail' );
    		$success = $delete = $nocrop = true;
    	} else {
    		$sizes = array( $target );
    		$success = $delete = $nocrop = true;
    	}
  2. Mr Brainz
    Member
    Posted 3 years ago #

    Hi there,

    Welcome to the world of WordPress!

    First of all, hacking the core files isn't a great idea. It'll only get you into a world of trouble down the line when you upgrade to newer versions.

    You're better to use filters and hooks to replace functions (though I'm not able to write these from scratch myself).

    What I think would be the best solution for you would be to work with 2 separate images, and use the "Multithumbnail" plugin to extend the the_post_thumbnail() function.

    So all you'd need to do is specify your sizes in your theme's function file

    add_theme_support( 'post-thumbnails' );
    add_image_size( 'additionalsize', 500, 400, true );

    Then enable the size for the multithumbnail plugin

    if (class_exists('MultiPostThumbnails')) {
    $additionalsize = new MultiPostThumbnails(array(
        'label' => 'Additional Size',
        'id' => 'additional-size',
    	'post_type' => 'post'
        )
    );

    You then use something like this to display the image you've chosen as your secondary thumbnail

    <?php if (class_exists('MultiPostThumbnails')
        && MultiPostThumbnails::has_post_thumbnail('post', 'additional-size')) :
            MultiPostThumbnails::the_post_thumbnail('post', 'additional-size'); endif; ?>

    That would be how I'd work around it. Though that might be a n00b cop-out as I'm not amazing at PHP.

  3. redannick
    Member
    Posted 3 years ago #

    Hi Mr. Brainz, thanks for your comment.

    I'd certainly prefer to 'extend' these functions instead of hacking like this - I'll look into hooks and see if I can do this here. MultiThumbnail looks fine, but it would mean that the user will have to upload duplicate images which may get confusing and this will further confuse the custom theme code for displaying the appropriate thumb in the correct location. My method may be messy but the end result is simpler for the user I think.

  4. redannick
    Member
    Posted 3 years ago #

    It seems to me that hooks like hooks and filters aren't really meant for this type of hack. I looked into overriding the function instead of having the hack in the core file and it seems that php won't let me do this. I guess the alternative would be to somehow ask it to use, for example, my version of media.php instead of theirs - is this possible does anyone know?

  5. TheDoubtfulRebel
    Member
    Posted 3 years ago #

    I agree with redannick that his solution is better. I find myself in the same situation and I was considering the the hack. However, after some thought, I created some code that does exactly what redannick wants, WITHOUT the core hack.

    The following code can go in your functions.php file:

    [Code moderated as per the Forum Rules. Please use the pastebin]

    Obviously, the $my_image_sizes array is like a configuration file, and you should change it to have whatever custom images sizes you want (not mine).

    I hope this is helpful to redannick and others like us who were disappointed to find that "Apply changes to All image sizes" is a lie.

  6. redannick
    Member
    Posted 3 years ago #

    hey thanks TheDoubtfulRebel - that looks like a much better way of doing things than my hack - I'm needing to update shortly so will try this instead of the hack at that point.

  7. redannick
    Member
    Posted 3 years ago #

    Hi TheDoubtfulRebel,

    I've had a go at implementing this, but it still seems to require the hacks in image-edit.php for the options to show up here... any idea how this could be achieved from functions.php?

    many thanks

  8. luisrivera
    Member
    Posted 3 years ago #

    =(
    is not working...

    Warning: Invalid argument supplied for foreach() in /../.../.../functions.php on line 116

    // Hook into the 'intermediate_image_sizes' filter used by image-edit.php.
    	// This adds the custom sizes into the array of sizes it uses when editing/saving images.
    	add_filter( 'intermediate_image_sizes', 'my_add_image_sizes' );
    	function my_add_image_sizes( $sizes ){
    		global $my_image_sizes;
    		//this is the line giving the error
    		foreach ( $my_image_sizes as $my_image_size ){
    			$sizes[] = $my_image_size['name'];
    		}
    		return $sizes;
    	}
  9. ninjacolin
    Member
    Posted 3 years ago #

    TheDoubtfulRebel, could you repost that code?
    It seems kinda silly that all image sizes aren't available for custom cropping by default in the EDIT section.

  10. TheDoubtfulRebel
    Member
    Posted 3 years ago #

    Heh, I guess that was too much pasted code for the moderator's liking. As advised I have placed the code on 'pastebin':

    http://pastebin.com/yp9378J4

    redannick - It doesn't look like there are any relevant hooks/filters to add any custom labels/options on the edit image screen. In my case, I didn't need that. I just wanted to have "Apply changes to All image sizes" to ACTUALLY apply changes to all sizes. Not just the preset sizes, but all custom sizes as well. If you really need custom options there, you may still have to hack it... Goodluck

    luisrivera - $my_image_sizes is the configuration array from the code above. Did you change the name of the array? If so, you need to change it in all instances in my example code, including that line. That error leads me to believe that an array called $my_image_sizes was never defined, or not populated with anything.

    The code I pasted here (now pastebin), is working for me on WordPress 3.1.

  11. ninjacolin
    Member
    Posted 3 years ago #

    Hmm... so, you wouldn't happen to know of a way that we could crop JUST the medium sized version of an image, huh?

    I think the functionality redannick (and I) are after is being able to use that wonderful WP crop tool on any one size-instance of the uploaded image.

    Being able to crop one the custom sizes would be important too.

    (thanks for your support, man! good stuff)

  12. TheDoubtfulRebel
    Member
    Posted 3 years ago #

    I was just looking over the code again, and unfortunately, it doesn't look like you can do that without a 'hack'. The whole media system doesn't seem as extensible as it should be...

    But I agree that it would be great to have that ability (to save a crop for just one size [other than the thumbnail]).

    Goodluck on your solutions!

  13. ninjacolin
    Member
    Posted 3 years ago #

    Thanks, I was able to sucessfully use redannick's code.

    he had one mistype though. He forgot to open with a curly brace at:
    if ( 'nothumb' == $target )

    so the correct way should be:
    if ( 'nothumb' == $target ){

    It works pretty well. Thanks to both of you!

  14. ninjacolin
    Member
    Posted 3 years ago #

    redannick

    your code for /wp-admin/includes/image-edit.php ~ Line 613 has an ambiguous closing brace here:

    if ( $success && ('nothumb' == $target || 'all' == $target) ) {
    			$sizes = apply_filters( 'intermediate_image_sizes', array_keys($meta['sizes']) );
    			if ( 'nothumb' == $target )
    				$sizes = array_diff( $sizes, array('thumbnail') );
    		}

    Is that closing brace just a mistake or is there a missing opening brace on this if:

    if ( 'nothumb' == $target )
    				$sizes = array_diff( $sizes, array('thumbnail') );
    		}
  15. ninjacolin
    Member
    Posted 3 years ago #

    Also, when you crop an image the image is renamed to something with a long E number like: "myImagename-e1303127369443-thumbnail.jpg"

  16. TheDoubtfulRebel
    Member
    Posted 3 years ago #

    I just found a plugin that may help some people here:
    http://wordpress.org/extend/plugins/post-thumbnail-editor/

    It seems to work with custom image sizes as well. Of course I don't know if it's working out of the box, or if my other enhancements are making it detect the custom sizes.

    It allows you to pick an image size you want to crop, and then allows you to do the cropping in a popup.

  17. lucasrcosta
    Member
    Posted 3 years ago #

    The Post Thumbnail Editor does work, although the ui is not perfect yet.

    Another option is this plugin: http://wordpress.org/extend/plugins/regenerate-thumbnails/, which solves the problem by regerating one, many or all thumbnails. It does suck that you would have to use it for every new cropped image.

    I belive this is a bug (you have the functionality to create new thumbnail sizes but this is left aside when editing). This should be easy to fix inside the core. Would you agree?

    redannick, would you like to report it?

  18. tomasdev
    Member
    Posted 2 years ago #

    One approach i've tried:

    function my_admin_head() {
            echo "
            <script>
            jQuery(function($){
            	var jQueryLoad = $.fn.load;
            	$.fn.load = function(){
            		var result;
            		if( arguments.length == 3 ){
    	        		var c = arguments[2];
    	        		result = jQueryLoad.apply(this, [arguments[0], arguments[1], function(r){
    	        			c.apply(this, arguments);
    	        			if( r.indexOf('imgedit-wrap') > -1 ){
    	        				var last = $('.imgedit-label').last();
    	        				var input = last.find('input').clone().val('slideshow-full');
    	        				var label = $('<label class=\"imgedit-label\"></label>').append(input).append(' Slideshow');
    	        				last.after(label);
    	        			}
    	        		}]);
            		}else{
            			result = jQueryLoad.apply(this, arguments);
            		}
            		return result;
            	};
            });
            </script>";
    }
    add_action('admin_head', 'my_admin_head');

    I gave up because there is no way to save that new submitted value ha!

  19. zabatonni
    Member
    Posted 2 years ago #

    http://wordpress.org/extend/plugins/post-thumbnail-editor/

    this plugin is great, out of the box it finds your defined custom sizes from functions.php and allows you to change each separately.
    One big thing is that it leaves original image untouched so you can crop same custom size again and again from fresh original image.

    i really recommend this solution, rather then touching core

Topic Closed

This topic has been closed to new replies.

About this Topic