WordPress – Add Retina Image Support to Your Theme

Today, with increasing of high resolution devices, Client ask developer to add retina image support to their theme. Support Retina is to display high quality image on high resolution devices. This means we need to create high resolution images and to load right images based on screen resolutions.

There are some plugins available on WordPress for regular users to add retina display images. Searching a wordpress directory for plugin shows below 5 plugins on top

Each plugin show use different way to show retina images but internal all  includes two things, A detection script and a retina-ready image creation function. For developer who want to include the feature of displaying retina image to their theme, It very first step to select right JavaScript to detect the screen resolution and display the image.

Detect Screen Display

We need to display high quality image if user device is supporting it. The best way to detect a screen is using JavaScript.  I generally use a script called retina.js by Imulus. Its size is only 4kb and includes all the front-end functionality you need to detect a retina display and load the right image.

Copy retina.js file to your theme /js folder. It should be in right place to enqueue the script correctly.

Add following code to your functions.php file

add_action( 'wp_enqueue_scripts', 'retina_support_enqueue_scripts' );
/**
 * Enqueueing retina.js
 *
 * This function is attached to the 'wp_enqueue_scripts' action hook.
 */
function retina_support_enqueue_scripts() {
    wp_enqueue_script( 'retina_js', get_template_directory_uri() . '/js/retina.js', '', '', true );
}

Above code is enough to detect the screen display. Now we have to create function to create high quality image.

High Quality Image Creation

We need to add a function such that each time image is uploaded or added a high resolution image is created automatically and stored with @2x added to the filename. The detection JavaScript will search for @2x suffix in filename to load the retina-ready version of the image if required.

In order to make sure that a retina-ready image is created automatically whenever an image is uploaded, you need to hook into the appropriate WordPress filter. The correct one to use is wp_generate_attachment_metadata.

Add the following code in functions.php of your theme

add_filter( 'wp_generate_attachment_metadata', 'retina_support_attachment_meta', 10, 2 );
/**
 * Retina images
 *
 * This function is attached to the 'wp_generate_attachment_metadata' filter hook.
 */
function retina_support_attachment_meta( $metadata, $attachment_id ) {
    foreach ( $metadata as $key => $value ) {
        if ( is_array( $value ) ) {
            foreach ( $value as $image => $attr ) {
                if ( is_array( $attr ) )
                    retina_support_create_images( get_attached_file( $attachment_id ), $attr['width'], $attr['height'], true );
            }
        }
    }

    return $metadata;
}

The above function checks to see if the uploaded file is an image. If it is, then it processes it using the retina_support_create_images() function.

Create An Image

Now as we checked if image is added and its time to create high quality image.

This code will also be placed in functions.php

/**
 * Create retina-ready images
 *
 * Referenced via retina_support_attachment_meta().
 */
function retina_support_create_images( $file, $width, $height, $crop = false ) {
    if ( $width || $height ) {
        $resized_file = wp_get_image_editor( $file );
        if ( ! is_wp_error( $resized_file ) ) {
            $filename = $resized_file->generate_filename( $width . 'x' . $height . '@2x' );

            $resized_file->resize( $width * 2, $height * 2, $crop );
            $resized_file->save( $filename );

            $info = $resized_file->get_size();

            return array(
                'file' => wp_basename( $filename ),
                'width' => $info['width'],
                'height' => $info['height'],
            );
        }
    }
    return false;
}

By this function, new retina image will be created  with suffix @2x added to the name. Now detection script will work with these new image.

That’s all you need to do to make it work, but adding one extra function will help in reducing the usage of server bytes. This function is for deleting the image that we have created for retina display when original image is deleted.

Delete the Image

If is a good to delete the retina-image if original image is deleted.

Add following code to functions.php of your theme

add_filter( 'delete_attachment', 'delete_retina_support_images' );
/**
 * Delete retina-ready images
 *
 * This function is attached to the 'delete_attachment' filter hook.
 */
function delete_retina_support_images( $attachment_id ) {
    $meta = wp_get_attachment_metadata( $attachment_id );
    $upload_dir = wp_upload_dir();
    $path = pathinfo( $meta['file'] );
    foreach ( $meta as $key => $value ) {
        if ( 'sizes' === $key ) {
            foreach ( $value as $sizes => $size ) {
                $original_filename = $upload_dir['basedir'] . '/' . $path['dirname'] . '/' . $size['file'];
                $retina_filename = substr_replace( $original_filename, '@2x.', strrpos( $original_filename, '.' ), strlen( '.' ) );
                if ( file_exists( $retina_filename ) )
                    unlink( $retina_filename );
            }
        }
    }
}

In this tutorial we learn how to add support of displaying retina image in WordPress theme. This will help theme developer in adding retina support to their theme.

 

Thanks to wptuts+.