“Unraveling the JPEG” is a great deep dive into the JPEG image format.
This article is about how to decode a JPEG image. In other words, it’s about what it takes to convert the compressed data stored on your computer to the image that appears on the screen. It’s worth learning about not just because it’s important to understand the technology we all use everyday, but also because, as we unravel the layers of compression, we learn a bit about perception and vision, and about what details our eyes are most sensitive to.
Comes with interactive editors which allow you to adjust the JPEG data, and directly see how it affects the image.
Great in-depth writeup on how Discord struggled to resizing lots of images via their Image Proxy Service:
As Discord grew, the Image Proxy started to show signs of strain. The biggest problem was the Image Proxy did not have an even workload distribution, which hampered its throughput. Image proxying requests saw a wide variance of response times, with some taking multiple seconds to complete.
Eventually they created Lilliput, to resize a scale of images and generating first-frame stills of video:
Lilliput relies on mature, high-performance C libraries to do most of the work of decompressing, resizing and compressing images. It aims to do as little memory allocation as possible and especially not to create garbage in Go. As a result, it is suitable for very high throughput image resizing services.
Lilliput supports resizing JPEG, PNG, WEBP and animated GIFs. It can also convert formats. Lilliput also has some support for getting the first frame from MOV and WEBM videos.
Display a resized version of the original at the original size, with a blur filter on top to hide the artifacts.
Load in the bigger one.
Once the big version is loaded, replace the small image with the big one.
Now, at Medium they don’t just swap out the small image for the big one, but animate between the two. For this they render everything on a <canvas> element. The author of the post has recreated the animation using CSS filters:
Now I must say his self-made results aren’t that satisfying … the jump between the lo-res SVG and the original is too big. What caught my eye in said article however, is the mention of SQIP which yields some very – very – nice results:
It makes use of Primitive to generate a SVG consisting of several simple shapes that approximate the main features visible inside the image, optimizes the SVG using SVGO and adds a Gaussian Blur filter to it. This produces a SVG placeholder which weighs in at only ~800–1000 bytes, looks smooth on all screens and provides an visual cue of image contents to come.
# Generate a SVG placeholder and print an example <img> tag to stdout
# Save the placeholder SVG to a file instead of printing the <img> to stdout
sqip -o output.svg input.jpg
# Customize the number of primitive SVG shapes (default=8) to influence bytesize or level of detail
sqip -n 4 input.jpg
Essential Image Optimization is an free and online eBook by Addy Osmani:
Images take up massive amounts of internet bandwidth because they often have large file sizes. According to the HTTP Archive, 60% of the data transferred to fetch a web page is images composed of JPEGs, PNGs and GIFs. As of July 2017, images accounted for 1.7MB of the content loaded for the 3.0MB average site.
Per Tammy Everts, adding images to a page or making existing images larger have been proven to increase conversion rates. It’s unlikely that images will go away and so investing in an efficient compression strategy to minimize bloat becomes important.
Essentially Addy pushes forward two key factors:
We should all be automating our image compression
Everyone should be compressing their images efficiently
For the recent UK Elections the folks The Guardian wanted to show big images along with their push notifications. Being bandwidth-aware they wanted a solution in which they could use a template image (which could then be cached) and then draw some stuff onto it. Only problem: Service Workers don’t have access to the Canvas API.
Enter PngPong, an basic image manipulation library, they’ve created:
PngPong is a very, very basic replacement for the Canvas API in environments that do not support it – primarily, service workers. Instead, it manually manipulates the bytes of a PNG file to copy the contents of another image, or draw basic shapes (currently only rectangles).
Their code to handle push notifications looked something like this:
Inside addResultsToTemplate they heavy lifting would be done by PngPong, drawing some small rectangles onto the template pictured below, yielding a push notification as pictured at the top of this post.
The template used
Example PngPong usage:
} from 'png-pong';
// Create new PngPong instance
const pngPong = new PngPong(imageArrayBuffer);
// Draw a 30px red square 10px from the top and 10px from the left
const shape = new PngPongShapeTransformer(pngPong);
shape.drawRect(10, 10, 30, 30, [255, 0, 0])
// Copy a 50x50 image 10px from the top left of the source image,
// and draw it 30px into our target image.
const toCopyFrom = new ArrayBuffer();
const imageCopy = new PngPongImageCopyTransformer(toCopyFrom, pngPong);
imageCopy.copy(10, 10, 50, 50, 30, 30);
// Run the transforms
Great new package by the folks at Spatie to working with images in PHP, powered by Glide. Glide itself is great, but uses an URL based approach (which has its benefits); yet in most cases I find myself using a code based approach. This is where spatie/image comes into play:
spatie/image wraps up Glide so all its methods can be used using PHP code.