Convert 32 bit png to 8 bit png with ImageMagick by preserving semi transparent pixels

Karmar picture Karmar · Dec 25, 2012 · Viewed 27.1k times · Source

I want to convert 32 bit png to 8 bit png with ImageMagick, but semi transparent pixels are lost. How to solve this problem? The command that I am using is the following

convert original.png PNG8:output.png

Answer

Ilmari Karonen picture Ilmari Karonen · Dec 25, 2012

Apparently, even though the PNG format actually allows any and all of the colors in an 8-bit indexed color PNG to be fully or partially transparent, ImageMagick's "PNG8" format specifier only supports GIF-style 1-bit transparency.

It's possible to produce indexed 8-bit PNGs using ImageMagick by not using the PNG8: specifier, but simply using -colors 256 or -colors 255* to reduce the number of colors in the image. Unfortunately, at least based on my tests using ImageMagick 6.8.9, the resulting images have some rather weird and quite unnecessarily ugly color quantization artifacts.

Fortunately, there's a much better tool for this specific job: pngquant. Using it, converting a 32-bit RGBA PNG into an 8-bit colormapped PNG with minimal quality loss is as easy as:

pngquant 256 < original.png > output.png

As a quick demonstration, here's a simple test picture (a star with a semitransparent drop shadow) converted to 8-bit PNG using various methods:

Original pngquant 256 ImageMagick convert (-colors 255) ImageMagick convert (PNG8) ImageMagick convert (-colors 255, PNG8)

From left to right:

  1. Original 32-bit RGBA PNG
  2. Quantized with pngquant 256 < input.png > output.png
  3. Quantized with convert input.png -colors 255 output.png*
  4. Quantized with convert input.png PNG8:output.png
  5. Quantized with convert input.png -colors 255 PNG8:output.png*

*) In the comments below, it is suggested that -colors 255 is necessary "to reserve one entry for the 'background' color." Based on my testing, I have not observed this to actually be the case; using -colors 256 will still produce an 8-bit colormapped PNG, with quantization artifacts qualitatively similar to, but differing in details from, the output with -colors 255. Nonetheless, just to play it safe, I've used -colors 255 for the examples above. Reducing the colormap size by one color should not, in itself, significantly affect the quality of the results, as a test with pngquant 255 will demonstrate.