InsaniQuant high quality image quantizer
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
.gitignore
4x4x4cube.png
LICENSE
Make_config.mk
Make_defines.mk
Makefile
README.rst
coldepth.c
coldepth.h
coldiff.c
coldiff.h
depthred.c
depthred.h
idata.c
idata.h
iquant-bulk.sh
iquant.sh
main.c
mquant.c
mquant.h
palapp.c
palapp.h
palgen.c
palgen.h
types.h
version.h

README.rst

InsaniQuant

Author: Sandor Zsuga (Jubatian)
Copyright: 2013 - 2015, GNU General Public License version 2 or any later version, see LICENSE

Introduction

InsaniQuant is an image quantizer: it reduces the color depth of an image to fit it in some palettized mode. This particular solution is slower than the common ones, however (at least for me it seems so) it's quality is (usually) superior. It works together with the ImageMagick package to read common image formats, and PNGCrush to reduce the size of produced PNG images.

Uses of this program:

  • Trimming down the size of images used for web (typically site design elements). It can perform well in this regard thanks to ImageMagick's support for Indexed-Alpha images.
  • Trimming down the size of sprite sheets used in 2D games, such as Battle for Wesnoth. It can serve this purpose again thanks to that ImageMagick properly supports Indexed-Alpha images (not only colorkeying).
  • Producing images efficiently in decent quality for retro machines, such as an Amiga or RRPGE (both having 4x4x4 RGB color space), EGA (2x2x2 RGB) or VGA (6x6x6 RGB). Common image manipulation software is not quite suitable for this since they can't target a bit-depth limited palette.

Dependencies

The following additional packages are required to build and run this program:

  • PNGCrush, tested with version 1.7.9.
  • ImageMagick, tested with version 6.7.7-10.

Note that the program is tuned to work with a gamma of 2.2, so if necessary, you might have to transform the images to this gamma before quantizing.

Building

To build the program, the standard GNU toolchain is sufficient, the software itself has no external depencies apart from the standard C libbraries. Just do a "make" to build it.

Running

For interfacing with ImageMagick and PNGCrush, two scripts are provided:

  • iquant.sh: Quantizes a single image
  • iquant-bulk.sh: Performs bulk quantization on a directory of png images

iquant.sh

This script accepts 3 to 5 parameters as follows:

  • Input image file name. It can be any image which ImageMagick can read. It may have an alpha channel which will be preserved unmodified (creating an Indexed-Alpha image).
  • Color count between 2 and 256 to quantize the image to.
  • Output image file name. This must be a .png.
  • Optional target palette bit depth, between 1 and 8. By default 8 is assumed. You can reduce the palette bit depth for example to produce an Amiga or RRPGE compatible palette (4 bits). You may also specify 3 digits for seperate depths for R:G:B repsectively (such as to quantize to 3:3:2 RGB).
  • Optional dithering setting: a 'd' turns on dithering.

iquant-bulk.sh

This script accepts 2 to 4 parameters as follows:

  • Directory to process. All .png images within the directory will be quantized and replaced.
  • Color count between 2 and 256 to quantize the images to.
  • Optional target palette bit depth, between 1 and 8. By default 8 is assumed. You can reduce the palette bit depth for example to produce an Amiga or RRPGE compatible palette (4 bits). You may also specify 3 digits for seperate depths for R:G:B repsectively (such as to quantize to 3:3:2 RGB).
  • Optional dithering setting: a 'd' turns on dithering.

Some notes on the algorithms and behaviors

With all components of this quantizer the primary goal was to achieve a pleasant look on a variety of images used for testing. As such, it uses some quite different approaches to the usual Median Cut quantizer + Floyd Steinberg ditherizer combos.

The quantizer algorithm

This component is some own invention, based on old ideas and experimental quantizers I wrote in the past to get around the problems I experienced with palettes generated by software available to me. It iteratively reduces the color count by picking the least differing color, then re-arranging everything into the remaining "buckets". As such, it is slow. However, a definite advantage of this particular algorithm is that it can be made working to target a bit depth goal (or even a palette) which it will approach in a sensible manner with consistent quality.

Color differences

The differences between colors are calculated in a HSL (Hue - Saturation - Lightness) color model, tuned to the characteristics of human (my) vision, on a reasonable display properly calibrated to a gamma of 2.2. The importance of this is that the differences values obtained from this component reasonably well represent the actual perceived differences which is probably the most critical aspect of achieving a good quantization result.

To tune this part, you could use the provided 4x4x4cube.png image, quantize it with the program, and observe the result (you may also compare this to the results from other image editing software on this image). To simply shift around preferences for the axes of the HSL model, tune the constants in coldiff.c (the current setup there seems to be the optimal one anticipating any kind of input image).

Ditherizer

The ditherizer is designed to be as unobstrusive as possible while improving the image quality just as any reasonable ditherizer should. By unobstrusive it is meant that it is tuned to not spew "stray" pixels around the image, especially not ones which are "terribly" out of place. The solution itself is simple, without any memory, just considering immediate neighbors. This fits well with it's goals, staying pleasantly in the back.