Native Image Sizing “On the Fly” with WordPress

I tweeted it out not too long ago, and it seems to have gotten people’s attention. So why do WordPress theme developers still use TimThumb? One of the valid reasons seems to be dynamic image sizing. Of course if you’re using TimThumb for post thumbnails in your theme, your life saver is the add_image_size function — you don’t need “dynamic resizing” since all your thumbnails are of equal sizes throughout your theme.

However, the valid reason I seem to have bumped in, is the fact that sometimes you would want to use a specific size for an image, but only once, for one post or page. The add_image_size function here will add a lot of overhead, crunching all the uploaded images into the size you want to use only once. Like a shortcode that can resize and crop an image from your media library to whatever dimensions you tell it to:

[image src="http://example.org/wp-content/uploads/2012/03/image.png" width="150" height="150"]

Right, a shortcode (argh!) to dynamically resize an image. Fair enough, a lot of premium themes seem to have something similar, but mostly use TimThumb because it’s so simple. However, I’ve created an image shortcode function that resizes and crops images from the media library on the fly using the image_make_intermediate_size function available as early as WordPress 2.5!

It saves the resized image on disk, and returns the absolute URL to that image. Of course you’d want to add things like captions, alt tags and so on, but the basic idea is there. Why is this better than TimThumb?

  • It stores the image files on disk and uses absolute URLs to those images, meaning you won’t have problems hosting your thumbnails on a CDN.
  • It uses functions native to WordPress and works with the WordPress media library, so extra files are deleted when an attachment is deleted — no more junk in your cache/folder.
  • It doesn’t have a zero-day vulnerability :)

There are drawbacks too, like the fact that it’s a shortcode! Although I’m pretty sure we can use the same technique and hook it directly to the content, bypassing the shortcodes madness. Oh, and it doesn’t support remote files too, only the ones in your media library, but that’s a good thing, as we have all figured out by now.

Feel free to fork the Gist on Github and experiment with the code, I’m sure you can think of how to make it better, easier to use and faster. Thoughts and comments welcome, and thank you for stopping by!

About the author

Konstantin Kovshenin

WordPress Core Contributor, ex-Automattician, public speaker and consultant, enjoying life in Moscow. I blog about tech, WordPress and DevOps.

10 comments

  • Hi,

    great Idea and great to see someone finally using like_escape()! Some notes: You can use hwstring(); to get the width/height attributes at the end of the function. The absint(); at the end isn’t necessary. You already got it at the beginning of the function (sanitize-comment). If you’re using something like that, then you won’t need any built in sizes. A good advice would be to set the default sizes to a height/width of 0. This completely skips them. A handy class for image size genereation can be found here.

    Too bad you didn’t make this a repo, so we could use pull requests. Thanks for sharing anyway :)

    Best wishes.

    • Hi Kaiser, thanks for your comment and for the tips! I’m used to escaping and sanitizing user input right before any output, even if I’m doing it twice. This will save me (and others) time when I scan through the source in a month or two — I won’t have to scroll back up and look whether I escaped the values, because I can see them right there, where I’m printing/returning them. You can call me paranoid :)

      Thanks for the advices and sorry for not making a repo/plugin out of this. My main goal was to prove a point, not to build a kick-ass plugin or shortcode, but you’re always free to :) You can fork my Gist like Gennady did above or start a Github project. Feel free to link to it when you do :)

      Thanks again for stopping by!

    • Good question! Better return the original URL with the specified width and height :)

  • Ok, it took me now more than an hour to rework it completely, but here it is as a Gist. You can use it as mu-plugin and it now also has a template tag (for whatever reason :). The new attribute $class is also present and I’m still thinking about adding a caption. If you’re interested, I can make a repo or fork one that you make.

    • Kaiser, looking good, well done! You’re free to open up a project on Github, I just don’t have the time to maintain it, and don’t want to make empty promises. I like your coding style, it’s quite clean and original in some places too!

      One thing I noticed a few things though. You’re passing $this->atts to get_image which expects no arguments. Your __toString method’s return type is void according to the comment block. Your __toString method should return a string, but if things go wrong it can sometimes return a WP_Error object from get_image. Also, you keep using $class throughout the code, which is never defined. You probably meant $classes.

      Hope that helps. Keep up the good work!

    • Perfect catch! Updated the gist with error for non-guests/non-subscriber roles and fixed the classes attribute. Let’s see if I find some time to make a repo later on. :)