Responsive images for web
Responsive web design has become the norm for modern websites and web applications, providing a consistent experience across a variety of devices and displays. But, the wide range of devices makes difficult to adapt designs and contents for all those screen sizes and pixel densities, optimizing the display for each device.
Responsive images allow the web browser to produce a rendering that closely matches the intent of the designer. This improves user experience but it also puts an additional burden on the development and operations teams, who now have to create and deploy numerous image asset variants as well as the default image.
Variants generation and resizing
Resizing images allows to adjust the image size to different viewports and layouts through different devices. But it may be problematic in some cases, presenting artifacts that not best represent the original.
The problem arises because web images are digital representations formed by discrete units of information or pixels. Resizing an image means changing the number of pixels in the image and this needs to be mathematically performed using an interpolation algorithm to recalculate (resample) all the pixel values at the image.
As a result, the resampling process can introduce some kind of artifact depending on the content of the image. In fact, jagged edges are problematic upscaling (enlarge) images, while aliasing artifacts (moiré) are problematic at downsizing (reduce).
Aliasing and blurring
Aliasing is a signal processing effect of resampling that introduces distortion and artifacts. Interpolation algorithms introduce anti-aliasing filtering to avoid moiré artifacts and aliasing distortion in general. This results in a resized image that can become significantly less sharp.
Moiré is a type of aliasing artifact that may occur when downsizing images. This shows up in images with fine textures which are near the resolution limit. When these textures are downsized surpassing their resolution new patterns appear, like in the example below, where a new pattern appears that does not correlate with the texture on the wall.
Interpolation algorithms which preserve the best sharpness are more susceptible to moiré, whereas those which avoid moiré typically produce a softer result. This is unfortunately an unavoidable trade-off in resizing.
One of the best ways to combat resize softening is to apply a follow-up unsharp mask after resizing an image — even if the original had already been sharpened.
This effects introduced by resizing operations makes important to understand how these algorithms perform resampling operations. How they handle throwing away pixels when the image is going to be smaller and how they handle adding pixels when the image is going to be larger.
Resampling is a way to calculate output pixels taking into account surrounding input pixels. It helps to avoid local geometry distortions, giving well- predictable output quality for a wide range of scaling factors (the ratio of input image dimensions to output image dimensions).
Several interpolation algorithms are available for image resampling, being the most common the non-adaptive methods. Recall that all non-adaptive interpolation algorithms always face a trade-off between three artifacts: aliasing, blurring and edge halos.
Four are the most common algorithms available to resize images:
Nearest Neighbor is the most basic algorithm and it only considers the closest pixel to the interpolation point. This has the effect of simply making each pixel bigger when is used upscaling (it is used to preserve a pixelated aspect). It requires the least processing time of all the interpolation algorithms, however it produces heavy aliasing in downsizing.
Bilinear interpolation considers a weighted average of the closest 2x2 (4 pixels) surrounding pixel values to arrive at its final interpolated value. For instance, when the size is halved all know pixel distances are equal, so the interpolated value is simply their sum divided by four. This results in much smoother looking images than other interpolation algorithms, and it is now rarely used because of its low quality results.
Bicubic goes one step beyond bilinear by considering the closest 4x4 neighborhood of known pixels (for a total of 16 pixels). Since these are at various distances from the unknown pixel, closer pixels are given a higher weighting in the calculation. Bicubic produces noticeably sharper images than the previous two methods, and it is the standard resampling algorithm used in Adobe Photoshop.
Lanczos is a higher order interpolation algorithm which takes more surrounding pixels into consideration. It retains the most image information after an interpolation, and it is therefore extremely useful when the image requires multiple transformations (rotations / distortions) in separated steps.
The use of each of this options produces big difference with image quality. Lanczos shows the best quality results and is the recomended downsampling algorithm.
Abraia's resizing method
With image resizing, pixels are resampled, somewhat mixing the values of original pixels. In this process, a number of decisions should be taken, like the mixing filter or the treatment of color channels, among other factors. Depending on these decisions, different artifacts may appear from aliasing to blur or more subtle effects like turning off highlights.
We take care of all these decisions and best practices in imaging engineering to provide an optimized image resizing that preserves highlights throughout color channels.
Our image resizer provides best-in-class protection of highlights and detail without any noticeable penalty in terms of aliasing or blurring.
Rsponsive images on the web
<img> tag provides a number of features that enable the browser to
select the most appropriate image if the server provides multiple variants. If
the website deploys multiple different sizes of the same image, the web browser
can choose the size best suited to its current environment.
srcset attribute of the HTML5
<img> tag is the best way for delivering
responsive images. We can use it to specify a number of image asset variants
for different pixel densities and viewport sizes - the display space
available to the web browser -.
srcsetattribute tells the browser witch images and sizes are available to use. The
sizesattribute tells about image sizes for different breakpoints in the CSS.
For example, to define two variants - one for displays with standard pixel
density (1x), and a second for displays with double pixel density (2x), such as
the iPhone 6 and Retina Macs - we use the
srcset attribute and the
attribute to define a default image for browsers that not support that attribute.
<img src="https://abraia.me/images/quarterback.jpg?w=600" srcset="https://abraia.me/images/quarterback.jpg?w=600&dpr=1 1x, https://abraia.me/images/quarterback.jpg?w=600&dpr=2 2x">
w=600 specifies our width of design while the
defines the device pixel ratio. All those images do not exist (only the
original image is stored) and they are generated and cached on the fly when
they are requested.
dprURL parameters, we can simplify the amount of effort it takes to generate the
srcsetattributes on our images.
A more sophisticated example defines a number of image variants to display,
according to the width of the viewport. The
sizes attribute specifies that
the browser must render the image at 600 pixels width if the viewport is wider
than 36em and use the entire viewport otherwise. The browser determines how much
space is available for the image, and selects the image asset variant that best
fits the available space, typically “rounding up” to the next width (w suffix)
and internally resizing the image to fill the space exactly.
Thus, using the sizes attribute, we are targeting two queries for behavior for the images. At a viewport of 36em or above, the images will display at 600 pixels. Below that size, the images will display at the full size of the viewport. At those sizes, the browser will determine which image to load in when the page is rendering for the given target size.
<img src="https://abraia.me/images/racecar.jpg?w=480" sizes="(min-width: 36em) 600px, 100vw" srcset="https://abraia.me/images/racecar.jpg?w=100 100w, https://abraia.me/images/racecar.jpg?w=240 240w, https://abraia.me/images/racecar.jpg?w=480 480w, https://abraia.me/images/racecar.jpg?w=640 640w">
This approach to delivering responsive images by specifying a range of image asset variants is easy to code and highly effective. However, it presents challenges in terms of creating and managing the image variants themselves. You have to do a great deal of pre‑production image resizing and deploy a much greater number of files on the server. It can be time‑consuming to fine‑tune the optimum number and size of each variant, which then leads to difficulty in testing that each image asset variant is accessible.
<img src="https://abraia.me/images/action-beach-fun-leisure.jpeg?w=320" srcset="https://abraia.me/images/action-beach-fun-leisure.jpeg?w=1920&h=600 1920w, https://abraia.me/images/action-beach-fun-leisure.jpeg?w=1024&ar=16:9 1024w, https://abraia.me/images/action-beach-fun-leisure.jpeg?w=640&ar=4:3 640w, https://abraia.me/images/action-beach-fun-leisure.jpeg?w=320&ar=1:1 320w">
With Abraia you can easily automate the variants generation from the original image, making sure they look good and have a small enough footprint to improve the website's performance.