On The Fly Image Processing Causes More Problems Than It Fixes

Update 2017-03-07: We’re now offering a better solution to on-the-fly image processing.

Images are the bread and butter of the web. Without images and other media the web would be quite different and not nearly as enriching; they are like a rug that really ties the room together. However, there is a concerning trend in the WordPress community to use on the fly (OTF) image processing libraries. Avoidable compatibility issues arise when themes and plugins forego WordPress’ built-in image resizing functionality in favor of OTF processing libraries.

In this article I’ll be going over the implications of OTF processing in WordPress, the benefits of following image standards, and how to get along with images (and subsequently other developers) in a WordPress environment.

What Is On The Fly Image Processing

Before we dive too deep, I should briefly explain what OTF image processing is, how to spot it, and where you can typically find it within WordPress projects. OTF image processing, also known as on-the-fly cropping, enables developers to reshape, crop, and filter images through the use of URL parameters (old school) or manipulation classes (more common approach nowadays). Using OTF processing enables the developer to define one-off, custom dimensions and manipulation of images as they need it.

Many developers use OTF processing due to the ease of use and implementation. Often it is a simple as adding a WordPress plugin, or just a file include, to start making use of OTF processing in any PHP-based CMS. Furthermore, front-end developers can use many OTF libraries because to their simple, concise syntax. Due to this flexibility, developers can keep their toolboxes lean from project to project and have more overlap between design (front-end) and development (backend).

Sounds great? Not in practice.

Two common areas where you can find OTF processing in WordPress are in plugins/themes and custom solutions. It is common for developers of themes and plugins to rely upon a manipulation class like Aqua, VT, TimThumb, or Smart Image Resize (if you’re unsure if a plugin or theme uses OTF processing, have look in it’s source code for classes named Aqua_Resizer, VT, TimThumb, Smart_resize_image etc).

I have also found custom cropping solutions are common in design/advertising agencies that do a lot of client work. Developers are usually pressed for time and look for shortcuts where they can find them – I know I have been guilty of this in years prior.

Maybe That’s Just Your Opinion, Man

By now I imagine many of you are probably asking…

“What’s the big deal‽ I can get my images to output as intended using OTF processing, I don’t need to make use of cumbersome WordPress image sizes, and it’s super quick. Why should I care? Maybe standardized WordPress images are just your opinion, man!”

The Dude: What's the big deal, man?

The answer is as simple as getting along with others.

If all plugins and themes follow the same rules/patterns, compatibility issues are minimal. However, if one plugin deviates it can cause a whole host of problems when interacting with other plugins/themes and WordPress core.

An example of this that comes to mind is when WP Offload S3 is paired with common OTF processing libraries (found in plugins or themes). WP Offload S3 allows you to place your entire media library (and all applicable image sizes) up in S3 and serve it through a CDN. In order to ensure predictable outcomes, we rely heavily upon standardized WordPress conventions for handling images and the media library. We target standardized code like this as accommodating custom solutions is a losing battle.

With WP Offload S3, images cropped OTF are often not uploaded as we have no way to determine details of the images as there is no record of the image in the database (in the form of post or postmeta data). If a OTF processing library does save this information in the database, it is typically saved as postmeta but makes use of custom keys rather than standard attachment metadata. The end result of this ‘no metadata’ scenario can be missing images or images that cannot be offloaded to S3 and can result in images not loading for end users.

A few other big ticket implications of OTF processing…

  • Performance – Each time an image is cropped it loads the OTF processing library. On a page with 100s images this can cause some serious spikes on server resources. Now imagine 1000s of users visiting that page simultaneously.

  • Future Friendliness – WordPress images are getting better with each subsequent release. For example, in v4.7 PDF enhancements are coming to the media library including better previews; how cool is that! Not to mention the many other features being added in this single release. OTF image processing libraries don’t have nearly the same developer resources at their disposal.

  • Security – Many of these libraries are plagued with security issues. File inclusion exploits are common place for a lot of OTF processing libraries and it’s child’s play to take advantage of. TimThumb, for example, has been impacted many times over the years with security exploits resulting in millions of sites having problems.

  • Responsive Images – OTF libraries quickly lose their appeal of immediate implementation when working with responsive images due to the length of code required for every instance where OTF libraries output a different size. WordPress’s core functionality (out of box) includes robust responsive image support.

Let’s learn from the past, and build together with core functionality.

Images Done Right

Thankfully, there are better ways to handle images in WordPress to ensure all plugins can get along together. If you make use of OTF processing libraries today and are worried about refactoring nightmares at this point, try not to worry as WordPress makes it easy to handle images correctly.

Adding Image Sizes

Since v2.9, WordPress has had support for custom image sizes. Over time the image sizes feature has matured and should support most (if not all) custom image size needs within a theme context.

It is very simple to implement a new image size in a functionality plugin or even your functions.php file by making use of the add_image_size function and the after_setup_theme action. Let’s look at a short example…

if ( ! function_exists( 'biglebowski_theme_image_sizes' ) ) {

    function biglebowski_theme_image_sizes() {
        add_image_size( 'feed-cropped-thumb', 300, 150, true );  // cropped, 300 x 150
        add_image_size( 'feed-header', 600 );                    // 600 x unlimited
    }

    add_action( 'after_setup_theme', 'biglebowski_theme_image_sizes' );
}

With this simple function, we’ve checked for conflicting code, registered two new image sizes, and hooked on to the after_setup_theme action. Because the image sizes are registered within WordPress, we can now make use of filters and actions such as intermediate_image_sizes.

When it is this simple to use built-in WordPress functionality for images, why not use it?

Caveats and Tools

Often when making use of image sizes you will run into instances where you need to resample/regenerate images as you have registered a new image size or modified an existing one. This is where some handy tools can come into play.

Regenerate Thumbnails is a simple and lightweight plugin that allows you to regenerate your images with all active image sizes. This tool is useful for media libraries but can take quite a while to complete on larger libraries.

WP CLI is a command-line interface for WordPress currently maintained by Daniel Bachhuber; a sharp dude you’ll want to follow. You can perform media regenerations via the command-line using the wp media regenerate and they are regenerated to all applicable image sizes. This tool is useful for larger media libraries and in environments where you have command-line access.

It is worth noting that you don’t need to create a plethora of specific image sizes as CSS has matured a great deal since the early 2000s and race for browser standards (Thanks, Mr. Zeldman). Often you can use larger images and slightly resize them in the DOM with traditional CSS. Going forward support for CSS3 features like clip-path and resize are becoming more supported by browsers and could be a good fit for your needs depending on your audience.

Heavy Lifting

I’d argue that 99% of the time, add_image_size can accommodate most developer needs. For those that need powerful image manipulation tools such as Imagick or GD, I’d still strongly suggest making use of core functionality surrounding media and the media library. However, if you do need to step into the land of PHP image libraries, please opt for the WP_Image_Editor class. Since v3.5, this class has abstracted much of the functionality in GD and Imagick, and is a tool for heavier server-side lifting when manipulating images (such as watermarks or color filters).

Let’s look at a brief snippet using WP_Image_Editor safely (to mirror/flip an image) with an existing WordPress attachment already uploaded that has an attachment ID of 42.

// Include if needed
require_once ABSPATH . "wp-includes/class-wp-image-editor.php";

// Base image/attachment
$attachment_id = '42';
$image_path    = get_attached_file( $attachment_id );

// Load the editor
$modified_image = wp_get_image_editor( $image_path );

// Check for any errors when loading WP_Image_Editor
if ( ! is_wp_error( $modified_image ) ) {

    // Flip the image, crank up the quality
    $modified_image->flip( false, true );
    $modified_image->set_quality( 100 );

    // Save image file, update metadata
    $saved_image = $modified_image->save();
    $meta_data   = wp_generate_attachment_metadata( $attachment_id, $saved_image['path'] );

    wp_update_attachment_metadata( $attachment_id, $meta_data );
}

We’ve loaded up our image and passed it into our WP_Image_Editor class for manipulation. Then we saved the image file and updated the metadata associated with it. This last step, updating metadata, is quite important if you are modifying image dimensions, the filesize of the image, etc. When updating metadata of an attachment you are saving important information to the database allowing others (and yourself) to access and further work with the attachment. This includes proper deletion of images. Having the relevant metadata of an image will allow you to ensure all resized images are removed when an image is deleted from the media library and no orphan image sizes are left behind.

If you are uploading a whole new image (either through WordPress or an external source like an API), you can still make use of the WP_Image_Editor class for any trickier image manipulation. You’ll want to be sure to latch onto media_handle_upload for the initial upload as it handles much of the upload process (file saving, metadata extraction, etc.) in a single function.

In the rare case that you need even more power there is hope; you can extend the WP_Image_Editor class! This is not for the faint of heart and can quickly get off the rails of standardization. But, if you extend the base class responsibly and always make use of the media library, you should be able to add more options and methods to WP_Image_Editor. For examples of this, take a look at the WP_Image_Editor_Imagick and WP_Image_Editor_GD classes. They extend the base editor class to work specifically for the two respective PHP image libraries and are very well commented.

Early in development, if you approach your image needs (especially those that require heavier lifting) with compatibility in mind you’ll be on the right path to playing well with other plugins, themes and WordPress core.

Where From Here?

WordPress core is always being updated and with it comes stability, security and new features. The additions in 4.7 alone are significant to extending the media library further and this is a single release.

Furthermore, say you find a shortcoming in how WordPress handles images. The true beauty of WordPress is that it’s open source. You can discuss a new feature with the WordPress community by submitting a Trac ticket, chatting on WordPress Core Slack, or writing a blog post about the feature. If you find a bug you have the power to report it and/or patch it yourself.

Let’s finally rid the WordPress community of OTF image processing libraries and instead rely upon core functionality. Compatibility with other developer’s code (whether a theme or plugin) should be easy if we all work from the same set of rules.

About the Author

Ian McFarlan

Ian is a PHP and WordPress developer in Ontario, Canada. Coming from an advertising background, he loves to create powerful, easy to use tools. He has a bit of an addiction to learning.

  • Brian Larson

    Great article! Do you have any suggestion on a project where you’re dealing with many small and old images in which you cannot get larger sizes of but you need to stretch/size them up (not ideal of course) to work with a new design? Would the only option be batch processing the source images (to be sized up) and then regenerating media? Seem like there could be some sizing up and THEN down which could make for an even more undesirable result. Thanks in advance for any insight y’all.

    P.S. Madly in love with WP Migrate DB Pro and its add-ons. Use ’em daily.

    • Scaling up images can be problematic as the quality of images quickly deteriorates. If it’s only a slight difference in size you could probably get away with a slight loss in image quality. If at all possible, your source or original images should be the highest quality (down sampling other sizes needed).

      In your case, you might want to look at software that makes use of fractals to upscale your original source graphics before implementing native WordPress image sizes. Genuine Fractals (which is now called ON1 Resize – https://www.on1.com/products/resize10/ ) has been around for a long time and might help you get those source graphics to larger dimensions.

      • Brian Larson

        Thank you for the awesome info and advice!

    • Brian, you might want to look into Filestack. Using their image resizing API, you can upsize images on the fly as well as generate responsive images even using external image URLs from a CDN such as Amazon S3.

      https://www.filestack.com/docs/image-transformations/enhancements#upscale
      https://www.filestack.com/docs/responsive-images

      • Brian Larson

        I’ll check it out. Thank you Ben!

  • Jeremy Benson

    Nice Article. I have two questions:

    I understand the concern about server resources when it comes to OTF, running that code for each visitor/image would imply a lot of overhead. Is this still an issue when a complete caching solution is being used? Ideally the OTF code would only run when new caches are being generated, which sounds pretty manageable.

    Obviously this all takes a back seat to the ‘shadow-meta’ or no database reference issue that you voiced, but my second question is (assuming that you’re using OTF that creates meta) doesn’t adding wordpress image force the creation of multiple image sizes for each image that you upload? it may not sound like much but if you go full-blown image size route, and create ideal image sizes for each use case this could lead to a lot of server space overhead. What if some of the sizes are only used in a few rare contexts? Wouldn’t WordPress still generate images for every size? If there was a way to control which thumbnail get generated based on some other meta value it would make more sense to me. Probably not an issue if you use S3 offload, but it could be an issue on smaller hosting plans.

    • Caching solutions with OTF processing would mitigate resource spikes. However, any OTF solution will still load all WordPress functionality around images by default; why not lean on the already loaded functionality instead of loading redundant functionality through OTF libraries?

      The number of image sizes can definitely get out of hand, especially with image heavy designs. Something that has helped me in the past with this is planning out your image sizes (with a designer if available) leaning towards fewer, more flexible image sizes. For example, if you have a 600×600 thumbnail you could make use of the same image size for an instance that requires 450×450 (matching aspect ratios helps).

      When I ran into instances where many image sizes where required for a given design, I usually had access to better server hardware due to the client/content/gig. The larger, more complex the site typically meant the larger the budget and better servers. Where this wasn’t an option, WP Offload S3 was a great solution to free up disk space on the server.

    • Jeremy,

      I’ve certainly run into the situation where using additional WordPress image sizes creates a nightmare of many images for each image size necessary. In some cases because of the needs of the layout, WordPress was generating 8 images for every image uploaded to the website. Things really got out of hand. We started looking into alternate solutions and are now using Filestack’s API to generate images on the fly at the necessary size required by the containing element of the image. You can read more about it here:

      https://www.filestack.com/services/image-transformations
      https://www.filestack.com/docs/responsive-images
      https://www.filestack.com/docs/image-transformations

      We’ve found this massively decreases load time on websites with large images and allows us to resize and crop images per the needs of the theme/design. And it works well with external image URL’s. So we offload the user uploaded images to a CDN such as Amazon S3 or RackSpace Cloud Files and then pass that URL on the image request as the data-fp-source with Filestack and we get the best of both worlds. We get OTF image sizing without generating a ton of extra images in WordPress and the ability to use a CDN for image delivery. Filestack also includes a CDN that you can utilize as well.

  • You got my attention 🙂
    I’m planning to purchase and use WP Offload S3, but I use Imagify and I think it may be a OTF service. If so, what do I have to do (before installing WP Offload S3)? Changing to an alternative option like “Optimus Image Optimizer” will keep my image files optimized and compatible with WP Offload S3?

  • Ulrich

    It is interesting that you mention `wp media regenerate`. There is an issue open for it and S3 offload https://github.com/deliciousbrains/wp-amazon-s3-and-cloudfront/issues/284

  • I think it would make things a lot easier if add_image_size() could be used contextually, e.g. I’ve run into an issue today where Yoast SEO sends og:image and twitter:image as the original uploaded image. In some cases these are 10MB+. I can filter the plugin so that the large image size is used instead, but what I’d prefer to do is send properly sized images as per Twitter and FB’s differing specs. If I could use add_image_size conditionally and only generate those additional image sizes for specific images as required, rather than globally, that would be very helpful.

    • alpipego

      If you use a plugin (Disclaimer: written by me) like https://wordpress.org/plugins/resizefly/ you can use add_image_size() but the image is only created when it is acually being requested. So not every image will be resized to facebook and twitter image sizes.

  • Li_An

    Very interesting post. Do you think such a plugin is a better solution ? https://wordpress.org/plugins/image-processing-queue/