Announcing exoquant, high quality image quantization library

Exoquant is a very high quality image quantization library (ie. for converting 32-bit (true-color) images to 8-bit (indexed) images. The quality of its output is at least on par to any other image quantization I know about. The library covers all aspects needed to convert images to 8-Bit, including quantization, palette optimization and remapping with dithering.

Use cases for image quantization today are mostly to decrease the file sizes of images, eg. for web projects, as indexed images can be quite a bit smaller than the original true-color versions, without any real visible differences.


This is my first published Rust crate, so I expect some rough edges to be still in place, but the library is feature complete minus some small tweaks to the colorspace/gamma handling. Expect minor API breakage between releases until v1.0.

Code / API reviews are definitely welcome at this point, if someone with more Rust experience is interested in doing this for this library.


pngeq is small command line tool utilizing the exoquant library to convert 24/32-bit PNGs to 8-bit PNGs. It serves as an example for using the library, as well as an easy way to try exoquant on your own images.


Very cool. I don’t know much about quantization algorithms, but I’ve used the color_quan crate before (which uses Neuquant algorithm). Can you talk a bit about the differences between the two crates?

1 Like

Thanks for your interest. In my experience, Neuquant does quite a good job on images with a limited number of color gradients, in those cases Neuquant and exoquant are on about the same level. On images containing a lot of different colors however, Neuquant does not perform nearly as well. (For example, on an image like this.)

I’d expect exoquant to beat Neuquant on images with an alpha channel, but I haven’t really tested this.

One big advantage of Neuquant is it’s memory usage which is much, much lower than exoquant.

You might want to install pngeq and run it on a few typical examples of your input images and see if it makes enough of a difference for you to switch.


I just looked up what you are using color_quant for, and I think, since vibrant-rs is only interested in 6 colors from the input image, Neuquant should be perfectly adequate.

Awesome job on this library, btw. I’m in the process of using it for an iOS app which I call into from swift.