1

I need a lot of various image sizes in my theme. I know how to add them with the add_image_size() function in functions.php.

But those defined sizes will create a lot of files for every uploaded image. Even if the images don't need all of the sizes but only certain ones, depending on where in the theme they get used.

Isn't this a huge waste?

So I thought I do this in my theme:

the_post_thumbnail(array(258, 190)); 

But this doesn't work reliably. Often the numbers seem to be completely ignored. How does the arbitrary size array work in WordPress?

I am confused. :)

  • I have written the Dynamic Image Resize plugin exactly for that case. Star it on GitHub, clone it, use it. – kaiser May 26 '14 at 17:23
  • @kaiser why don't you add this as an answer, and give a short description how your plugin works. I would think that a proper answer could be more useful that a short comment that might be missed :) – Pieter Goosen May 26 '14 at 17:48
  • @PieterGoosen Because it's a plugin recommendation - there is this answer already, but basically it should be a duplicate of one of those. – kaiser May 26 '14 at 18:11
  • @kaiser +1, understood :) – Pieter Goosen May 26 '14 at 18:15
2

Docs, docBlocks and Codex ...

Basically you have a very simple mistake: The $attributes array is the 2nd argument:

function the_post_thumbnail( $size = 'post-thumbnail', $attr = '' ) {
    echo get_the_post_thumbnail( null, $size, $attr );
}

How it works internally

1)

The HTML itself gets built by wp_get_attachment_image().

2)

Later on, inside this function, the next relevant function call is

$image = wp_get_attachment_image_src( $attachment_id, $size, $icon );

3)

In there, image_downsize() gets called and this is the first point where you can jump in and short circuit the whole system and simply return a custom sized image:

if ( $out = apply_filters( 'image_downsize', false, $id, $size ) ) {
    return $out;
}

4)

If that does not happen, you can look further and the next function call is

// $size: One of the registered image sizes: medium, large, full, custom, etc.
$intermediate = image_get_intermediate_size( $id, $size )

// Or: Use 'thumbnail' and retrieve the size in a different way:
$thumb_file = wp_get_attachment_thumb_file( $id ) )
getimagesize( $thumb_file )

As long as anywhere in there, the image URl can be obtained by core, it will call image_constrain_size_for_editor() and this function is able to do two different things:

  • Return the width, depending on the User Settings via get_option( "{$size}_size_w" )
  • Return a custom size (this will be checked first)

Before the function returns, it runs everything through a filter:

list( $max_width, $max_height ) = apply_filters(
    'editor_max_image_size', 
    array( $max_width, $max_height ),
    $size,
    $context
);

which is the next chance to intercept the call. $context will be either display (for a theme) or edit for a call in the admin UI.

5)

Then the return value will be run through wp_constrain_dimensions() to calculate the final size.

If all that worked, you will get back into wp_get_attachment_image_src() and immediately return the value from image_downsize() there.

6) Finally...

...you can use wp_get_attachment_image() (the proper way) and intercept the call for width/height in a lot of stages, call underlying functions.

Plugin for the rescue

As it's a pain to go trough all that again and again, I have written the

Dynamic Image Resize Plugin

which is freely available on GitHub and can be bundled with Themes or Plugins. It can be called directly with a filter in templates or can be used with a shortcode.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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