Navigation C API Pages Python bindings Applications

Dithering

All dithering filters can produce a grayscale or RBG pixmap. Dithering to palette or CMYK is not supported.

Dithering filters dither directly into the destination pixmap, the destination must be large enough to fit the source

Allocating filters allocate destination pixmap accordingly to the pixel_type and source size. These filters can return NULL in a case that malloc() failed or if the operation was aborted from the callback.

Dithering filters doesn’t work in-place as the destination has different pixel type than the source.

Floyd-Steinberg

#include <gfxprim.h>
/* or */
#include <filters/gp_filters.h>

int gp_filter_floyd_steinberg(const gp_pixmap *src, gp_pixmap *dst,
                              gp_progress_cb *callback);

gp_pixmap *gp_filter_floyd_steinberg_alloc(const gp_pixmap *src,
                                           gp_pixel_type pixel_type,
                                           gp_progress_cb *callback);

Classical Floyd-Steinberg. Produces good results at reasonable speed.

The error is distributed to neighbor pixels as follows:

X

7/16

3/16

5/16

1/16

And is thrown away at the image borders.

Sierra

#include <gfxprim.h>
/* or */
#include <filters/gp_filters.h>

int gp_filter_sierra_lite(const gp_pixmap *src, gp_pixmap *dst,
                          gp_progress_cb *callback);

gp_pixmap *gp_filter_sierra_lite_alloc(const gp_pixmap *src,
                                       gp_pixel_type pixel_type,
                                       gp_progress_cb *callback);

Sierra-Lite is comparable to Floyd-Steinberg, sometimes the result is sharper.

The error is distributed to neighbor pixels as follows:

X

2/4

1/4

1/4

And is thrown away at the image borders.

#include <gfxprim.h>
/* or */
#include <filters/gp_filters.h>

int gp_filter_sierra(const gp_pixmap *src, gp_pixmap *dst,
                     gp_progress_cb *callback);

gp_pixmap *gp_filter_sierra_alloc(const gp_pixmap *src,
                                  gp_pixel_type pixel_type,
                                  gp_progress_cb *callback);

Sierra is much sharper than Floyd-Steinberg because the error is distributed to a wider area. That results into edges are better preserved. Sierra also produces less patterns than Floyd-Steinberg in some cases.

The error is distributed to neighbor pixels as follows:

X

5/32

3/32

2/32

4/32

5/32

4/32

2/32

2/32

3/32

2/32

And is thrown away at the image borders.

Hilbert-Peano

Hilbert-Peano space filling curve based dithering.

The error value is distributed along the Hilbert curve.

The result is a little more noisy, however most of the time doesn’t create repeating patterns like Floyd-Steinberg. The result looks generally better to human eye, especially if there is more than a few bits to represent the results. On the other hand edges tend to be less sharp and the hilbert curve may leak into the result in the case of big areas colored with a single color.

#include <gfxprim.h>
/* or */
#include <filters/gp_dither.h>

int gp_filter_hilbert_peano(const gp_pixmap *src, gp_pixmap *dst,
                            gp_progress_cb *callback);

gp_pixmap *gp_filter_hilbert_peano_alloc(const gp_pixmap *src,
                                         gp_pixel_type pixel_type,
                                         gp_progress_cb *callback);

Ditherings

#include <gfxprim.h>
/* or */
#include <filters/gp_dither.h>

enum gp_dither_type {
        GP_DITHER_FLOYD_STEINBERG,
        GP_DITHER_SIERRA,
        GP_DITHER_SIERRA_LITE,
        GP_DITHER_HILBERT_PEANO,
        GP_DITHER_MAX,
};

gp_dither_type gp_dither_type_by_name(const char *dither_name);

const char *gp_dither_type_name(gp_dither_type dither_type);

int gp_filter_dither(gp_dither_type type,
                     const gp_pixmap *src, gp_pixmap *dst,
                     gp_progress_cb *callback);

gp_pixmap *gp_filter_dither_alloc(gp_dither_type type,
                                  const gp_pixmap *src,
                                  gp_pixel_type pixel_type,
                                  gp_progress_cb *callback);

Generic dithering API, allows you to parse dithering type by string, print dithering name by type and call dithering functions by type.

Original Image; Simple Conversion: RGB332, G8, G4, G2, G1

Original Image RGB332 G8 G4 G2 G1

Original Image; Floyd Steinberg Dithering: RGB332, G8, G4, G2, G1

Original Image RGB332 G8 G4 G2 G1

Original Image; Sierra Dithering: RGB332, G8, G4, G2, G1

Original Image RGB332 G8 G4 G2 G1

Original Image; Sierra Lite Dithering: RGB332, G8, G4, G2, G1

Original Image RGB332 G8 G4 G2 G1

Original Image; Hilbert Peano Dithering: RGB332, G8, G4, G2, G1

Original Image RGB332 G8 G4 G2 G1