Does using 8bit PNG with transparency increase file size significantly? No! PNG transparency compression is simple but clever.
I’ve learnt a new thing. I’ll be using transparent 8-bit PNGs for my images from now onwards. This caused me to go down a bit of a rabbit hole to find out how transparency compression works in 8-bit PNGs.
Previously I have done various experiments looking at different methods of saving diagrams and images with a lot of flat colour (as opposed to photographs, which are best saved as JPEG or WebP). You can read about those experiments here:
In those tests I didn’t look at using transparency (technically known as an alpha channel), because I assumed that adding an alpha channel would add a lot to the file size. However, I’ve recently realized that assumption may be wrong — alpha channels probably compress very well. So let’s do some tests.
Below is an image of some notes I made on the train this morning:
The following processes have been applied to this image:
- Photographed with a Sony A7iii that I have permanently set up for this purpose.
- A few processes applied in Photoshop:
- White levels auto-adjusted to the colour of the paper.
- Levels adjusted so that the black level is in the middle of the black ink colour, and the white level in the middle of the white paper.
- Desaturated.
- Background removed with the magic eraser set to 30, with aliasing.
- A layer with my chosen background colour applied.
- Exported at 8-bit PNG.
- Further compressed with Clop.
This is the same process I apply to all of my hand-drawn and coloured images I make for this site.
I always change the background colour to be the same as the colour I use here (#FAF6EA, which I’ve just discovered is named “old lace”). But what if I should want to change that colour in the future, or use the images in another setting where I want the background colour to be different? It would make sense to use a transparent background if there is not much overhead.
The image above is 126KB. What about if I export it as an 8-bit PNG with a transparent background? Let’s see. Here it is:
Ok, doesn’t look any different, which is good. What about the size? Apparently it’s 107KB! Much smaller! That makes no sense, as it needs to store both the image data and the transparency data. Why would that occur? Well perhaps that’s an idiosyncrasy of this image — the text is just black and white, so with transparency no colour data needs to be stored at all. That’s interesting, but makes sense. So what about an image with colour?
Let’s see what happens with the following image, which is 1920 by 1080. Here it is as an 8-bit PNG without transparency:
This is 390 KB after all my processes are applied. This is it as an 8-bit PNG with transparency:
The transparent version is 380Kb. Also a little bit smaller. Wow, well that’s a surprise. Why? Let’s find out. I’ll ask ChatGPT o1-preview, as this is a tricky problem that requires a bit of thought I think… Here is a summary of what it says:
- Having a background colour increases the palette, especially at the edges if they are antialiased. (Ah yes, this makes sense!)
- PNG uses a very efficient transparency encoding. Having more opaque pixels can actually increase the file size because the image encoding is less efficient. (That makes sense too I guess).
So, I’ve learnt something new — using transparency can actually result in more efficient image compression, at least with my style of images. So how does compression of transparency actually work? This has sent me down a bit of a rabbit hole…
How does transparency compression in 8-bit PNG files work?
I had assumed that there was essentially a separate representation of transparency, containing 256 levels, that was combined with the colour image — in such a scheme it would be impossible for the transparent version of the image to be smaller than the colour only version, because the transparent version would be the colour version plus the transparency map. But that’s not how it works. Take a look at section 4.2.1. Transparency information in this document:
PNG (Portable Network Graphics) Specification, Version 1.2
In 8-bit PNGs there is basically another chunk added to colour values, for transparency. If this addition is not there, the colour is treated as solid, This means that an individual colour can have a number of values in the colour index, being that colour at several different levels of transparency. If you imagine my black text above, that means at the edges of the text, there will be several different colours in the colour index. Since in 8-bit PNGs you only have 256 values to play with, the compressor optimizes the number of values in the index, so you will only get a limited number of transparency values (which is fine for edges, it will be impossible to notice visually. This also means that you only need to store those additional values for colours at the edges. So this method works very efficiently for flat colour diagrams and text.
One final thing — transparent images and Dark Mode
But, I have also thought of an issue — what about the web pages in Dark Mode? If I have dark text and someone has their browser set to Dark Mode, then they won’t be able to see the text. Is there a solution to that? I haven’t actually implemented Dark Mode on this site. It’s something I need to experiment with. I have added it to my list of things to do.
Hang on, I’ve just thought of a solution. If I add CSS to add an underlay on images then that will fix it. I’ll do that now. Here is the code:
/* Add a #FAF6EA background to all PNG images */
[src$=".png"] {
imgbackground-color: #FAF6EA;
}