Image optimization with Python and web services
Image optimization is a broad topic. Image can be converted to different file formats, resized and so on. All for saving bandwidth and decreasing time needed to load all elements of a webpage.
But what if we have an image that is ready to be posted on a web page by a user that isn't an expert? What tools can we use to automatically optimize uploaded images? In this article I'll go over few Python and service based solutions for image optimization.
Basics of image optimization
Optimizing images for usage on website is quite an important task. Smaller images load faster, consume less data cap and give functional website quicker. For a site with multiple images this may be crucial for achieving good conversion ratio of customers or lower bounce rate of users reading a website.
The very basic thing a website can do is to publish an image in best suited file format and keeping a limit to image dimensions. If a user is uploading a TIFF from a DSLR then such image can be converted to JPEG, resized if large and then Exif metadata could be dropped. Using additional, much smaller thumbnail is also a common practice.
TIFF is a lossless file format while JPEG uses compression algorithms to vastly decrease file size at the expense of quality. Also TIFF stores data as 16-bit integers where as JPEG uses 8-bit integers. Converting data from 16-bit to 8-bit reduces it size but it’s then less suitable for processing and will likely loose some data during conversion (note that monitors for the most part are 8-bit displays).
Images can also have Exif metadata attached to it - like brand and model of used DSLR, lens and exposure settings. By default this data is not visible when viewing such image. It can be shown by apps that can read Exif data. Removing Exif tags reduces image size a bit but you loose all information about the image. If needed you can extract Exif data and save it independently of derived image files that have been stripped of it.
Next we can look into file formats. Photographs will usually use JPEG, but there are newer formats on the rise like WebP. Such new file formats may provide additional advantages but they need to be supported by for example web browsers if you want to publish an image on the web. Also third party software (like image upload forms in web apps) must allow and handle such file formats which won't happen very often. As of the time of writing this article WebP is not supported on Safari (mobile and desktop) and not every image viewer can handle this file format.
Even in the case of JPEG we have some additional options like Progressive JPEG. Normal JPEG file will load and appear on a website from top to bottom. Progressive JPEG will load small subset of data across the whole image until it loads all - in such cases user sees whole image size and low pixel count preview of it early on. Progressive JPEG is recommended for large images.
Drawing-type images with limited color palette are often saved as lossless PNG files (and GIF before also). Lossy JPEG compression would destroy clear transition lines between colors (like text, chart lines etc) and it's not used. WebP could also be used as it can handle lossless and lossy image data. Some images that are often saved as PNG could be also saved as vector graphics - SVG. Some charts, drawings composed of a set of figures/shapes can be saved as SVG and then display at desired size - as vector graphics stores shapes data and can draw then in any scale, which can be a huge benefit for image size.
Animated GIFs are quite commonly used on social media sites. Their size can quickly increase with the amount of frames and animation length, especially for photograph-like frames. A much more efficient solution would be to use video file formats like H.264 MP4 or even better WebM. Such clip can be displayed on a web page with
Google has a much more detailed article about those topics - Automating image optimization.
And in the end picture HTML tag can be used to provide different image files for different screen resolutions. You can provide larger images to be loaded on desktop and smaller for mobile users. You can also provide multiple formats.
Image manipulation with Python
Python image manipulation libraries like Pillow, Scikit-Image or ImageMagick can resize and convert image files among many other features. You will find many tutorials and examples in their documentation. Basic example for Pillow would look like so:
piexif can be used to read, remove or copy Exif data. optimize-images is a Python command-line utility app that can optimize images of various file formats using Pillow and piexif.
Image optimization services
There is a lot of online services that offer image optimization. Most of them are commercial services and/or are tied to file CDN services (which is what big sites will want to use). Google lists couple of such services in their Lighthouse documentation - which is a website performance analysis tool you can find in for example Chrome browser (and it checks for image size optimization headroom).
Such services when more advanced will analyze the image file to determine best settings for optimization. Algorithms can detect features that would degrade to much with compression and prevent aggressive settings from being used. Actual tasks performed by such algorithms will be given company
squoosh.app is a showcase-type website that provides a nice large scale image comparison of the original and optimized image files allowing to play with settings and picking the most optimal.
To test out some of such services I used a DSLR JPEG image (6,2 MB in size) and two copies of it made in Kolourpaint and GIMP at 90 quality (3,1 and 3,0 MB). I've also added a small jpeg thumbnail (280 kB) and a PNG frame from a monochrome camera (465 kB).
Imagify did manage to optimize the PNG file down to around 82 kB (around 80% improvement). The image looks like it has smaller palette and some uneven transitions can be seen of the background from light to dark but overall the image is clear. Saving original PNG file as WebP reduces the size to record low 15,1 kB (where as JPEG would have 58,2 kB). WebP version of the DSLR image and it copies takes 2,2MB of size. Close to optimized versions and with quality tuning similar to what the optimization services do it should reach similar size if not better (squoosh example).
TinyPNG reduced the PNG by 73% where as GIMP and Kolourpaint copies got reduced by 58%. Kraken.io optimized PNG by 41% and JPEG thumbnail by almost 12%. Support for larger files wasn't available in the public free version.
Some of those services will offer an API which could be integrated in your applications to optimize uploaded images as you see fit:
Content creators can use desktop apps or plugins for such to optimize images at the time of preparing them for the article.