WebDev Tips - Alpha mask PNG technique
Reducing the file size of PNG images by extracting the alpha mask.
When you have to build a layer based client side product configurator like Land Rover or Scrambler, the first problem that you face is certainly related to the load of the assets that the user will have to download.
We are talking about hundreds of image layers to multiply by n views.
Assuming that we already have the PNG layers generated from a 3D software, the problem is now how to reduce their weight without losing quality?
Well, the technique that we adopted was able to reduce up to 50% the total weight of the images.
Let’s start for example with the following picture: it is an already compressed PNG image that weights about 400KB.
The purpose of the technique we used is to separate the alpha mask from the color level.
To do this you can use a CLI image editing software like ImageMagick, which is free to use and has a large support community.
$ convert bike.png -alpha extract -colors 8 alpha.png
This line of code:
-alpha extract -colors 8
extracts the alpha channel from the original PNG and reduces the number of colors of the image to 8 before writing the result to another file called “alpha.png”. With 8 color you can easily keep image edges nice and smooth.
As you can see now the image alpha.png has no transparency now.
To get i back you can write :
$ convert alpha.png -transparent white alpha.png
Now you can remove the alpha channel from the original image by turning it into a JPG to reduce its weight.
$ convert -flatten bike.png bike.jpg
Merge color JPG and alpha PNG
At this point we have to rebuild our image with the JPG and alpha.
This is really simple using an HTML5 canvas
ctx.globalCompositeOperation = 'xor';
First we draw the color JPG image to canvas, then we change the context globalCompositeOperation property to XOR and then we draw the “alpha.png” image.
With globalCompositeOperation = ‘xor’ the source image is combined by using an exclusive OR with the destination image.
What if I say you can actually use two JPG to achieve the same result?
Anyway, if you use a 8 colors PNG, there aren’t big advantages using a JPG also for the alpha mask, because the file size is almost the same.
So, at the end of the process, let’s see how much we have gained in terms of traffic data:
Original PNG file bike.png : 400KB
Converted to JPG bike.jpg : 200KB
Alpha channel PNG alpha.png : 25KB
Total converted image size bike.jpg + alpha.png : ~ 225KB
Total save : ~ 44%
This can be translated in money saving if you are using, for example, a CDN to serve your assets.
Thank you for reading.