Dynamic Resizing of Images in WordPress

Besides the fact that the function add_image_size has been available since version WordPress 2.9.0, I always thought that different image sizes in WordPress were too static. Although WordPress 4.4 introduced Responsive Images this did not really provide a solution to the problem—an improvement surely. The whole mindset behind image handling in this way is focused on device sizes and therefore adaptive web development instead of being device-agnostic and only focussing on the screen (or even viewport) size and implementing responsive design that focusses on best presenting the content on the given screen.

For this reason I have long had my own take on dynamically resizing WordPress media with the help of Aqua Resizer. With a little jQuery and window.devicePixelRatio we can determine the exact size an image has to have for the current display. We can then send this size via AJAX to the WP backend and the AQ-script either resizes the image or returns a previously resized one. Since it is impossible to consistently prevent browsers from downloading img source, the src attribute should have a placeholder image—something like a transparent 1x1px GIF. The image source url should be placed in a data-* attribute, e.g. data-src. To show an image even if a visitor prevents the execution of JavaScript, we should wrap the original img inside a noscript tag:

<img src="spacer.gif" data-src="https://example.com/wp-content/uploads/my-image.jpg" class="my-image-class" />
<noscript>
    <img src="https://example.com/wp-content/uploads/my-image.jpg" />
</noscript>

So much for the lazy loading basics… the present goal is not to implement image deferring techniques—although a big part has now already been done. But we want to show the user the ideal image for their screen size. With the following jQuery code the images are being requested via ajax and ultimately loaded. (Please note: For the sake of readability and to keep the code as short and precise as possible, security checks like nonce and AJAX referrer are obmitted):

jQuery(document).ready(function($) {
    $('img').each(function() {
        // get the image ratio
        var ratio = new Image();
        ratio.src = $(this).data('src');
        
        var targetEl = $(this),
            ajaxData = {
                action: 'resize_my_image', 
                width: $(this).width(), 
                height: $(this).width() * (ratio.height / ratio.width),
                source: $(this).data('src')
            };

        $.getJSON(ajaxurl, ajaxData, function(response) {
            targetEl.attr('src', response.src);
        });
    });
});

the corresponding php script looks roughly like this:

<?php

// include aq resizer script
require_once __DIR__ . '/path/to/aq_resizer.php';

// register the ajax handler
add_action('wp_ajax_resize_my_image', 'resizeImage');
add_action('wp_ajax_nopriv_resize_my_image', 'resizeImage');

function resizeImage()
{
    // explicit declaration of variables
    $width = (int) $_GET['width'];
    $height = (int) $_GET['height'];
    $url = esc_url($_GET['source']);
    
    // call the resize script
    $img = aq_resize($url, $width, $height);
    
    // echo the response
    echo json_encode(['src' => $img]);
    wp_die();
}

The AQ Resizer script is a bit dated. Therefore I came up with another method using WP_Image_Editor and I will present it soon. If you have questions or improvements for the above, either hit me up on twitter or fork the gists.