ErrorDiffusionDitherer Class

Provides an IDitherer implementation for error diffusion dithering. Use the static properties of this class to use predefined error diffusion filters or the constructor to create a custom one.

Definition

Namespace: KGySoft.Drawing.Imaging
Assembly: KGySoft.Drawing.Core (in KGySoft.Drawing.Core.dll) Version: 8.1.0
C#
public sealed class ErrorDiffusionDitherer : IDitherer
Inheritance
Object    ErrorDiffusionDitherer
Implements
IDitherer

Remarks

The constructor can be used to create an error diffusion ditherer using a custom matrix.

Use the static properties to obtain an instance with predefined parameters.

The ErrorDiffusionDitherer class uses an adaptive dithering technique, which disperses the quantization error of each pixels to the neighboring ones. Thereby the strength of the dithering is automatically adjusted by the algorithm itself, which provides good results also for palettes with uneven color distribution (which is not the case for ordered dithering, for example).

As the dithered result of a pixel depends on the already processed pixels, the ErrorDiffusionDitherer does not support parallel processing, which makes it slower than most of the other dithering methods.

The following table demonstrates the effect of the dithering:

Original image
Quantized image

Color hues with alpha gradient
Color hues with alpha gradient

Color hues with system default 8 BPP palette and silver background
Quantizing with system default 8 BPP palette, no dithering

Color hues with system default 8 BPP palette, silver background and Floyd-Steinberg dithering
Quantizing with system default 8 BPP palette and Floyd-Steinberg dithering

Color hues with system default 8 BPP palette, using silver background and Sierra 3 dithering
Quantizing with system default 8 BPP palette and Sierra 3 dithering

Color hues with system default 8 BPP palette, using silver background and Stevenson-Arce dithering
Quantizing with system default 8 BPP palette and Stevenson-Arce dithering

Grayscale color shades with different bit depths
Grayscale color shades

Grayscale color shades with black and white palette
Quantizing with black and white palette, no dithering

Grayscale color shades with black and white palette, using Floyd-Steinberg dithering
Quantizing with black and white palette and Floyd-Steinberg dithering

Grayscale color shades with black and white palette using Sierra 3 dithering
Quantizing with black and white palette and Sierra 3 dithering

Grayscale color shades with black and white palette using Stevenson-Arce dithering
Quantizing with black and white palette and Stevenson-Arce dithering

Calculation of the quantization error may happen in two ways. The publicly available algorithms usually calculate the error for each color channels, which usually provides good results with color palettes. However, when quantizing color images with a black and white or grayscale palette, this approach may fail. For example, if the quantizer returns black for a fully saturated blue pixel, the quantization error is zero on the red and green channels and 100% on the blue channel. The problem is that this error cannot be propagated to the neighboring pixels if they have the same color because adding any more blue to already fully saturated blue pixels will not change anything. Therefore, the ErrorDiffusionDitherer can propagate quantization error by brightness based on human perception, which is more appropriate for palettes with grayscale colors. The ErrorDiffusionDitherer tries to auto detect the strategy for each dithering session but this can be overridden by the ConfigureErrorDiffusionMode method.

The following table demonstrates the effect of different strategies:

Original image
Quantized image

Color hues with alpha gradient
Color hues with alpha gradient

Color hues with system default 8 BPP palette, silver background and Floyd-Steinberg dithering, using error diffusion by RGB channels
Quantizing with system default 8 BPP palette and Floyd-Steinberg dithering, using error diffusion by RGB channels (the default strategy for non-grayscale palettes)

Color hues with system default 8 BPP palette, silver background and Floyd-Steinberg dithering, using error diffusion by brightness
Quantizing with system default 8 BPP palette and Floyd-Steinberg dithering, using error diffusion by brightness

Color wheel
Color wheel

Color wheel with black and white palette, blue background and Floyd-Steinberg dithering, using error diffusion by brightness (the default strategy for grayscale palettes)
Quantizing with black and white palette and Floyd-Steinberg dithering, using blue background and error diffusion by brightness (the default strategy for grayscale palettes). All colors appear in the result with different patterns.

Color wheel with black and white palette, blue background and Floyd-Steinberg dithering, using error diffusion by RGB channels
Quantizing with black and white palette and Floyd-Steinberg dithering, using blue background and error diffusion by RGB channels. The fully saturated colors turned completely black or white.

A typical artifact of error diffusion dithering is a ripple effect, which often appears in homogeneous areas of the dithered image. This is due to the fact that most filters propagate quantization errors mostly to right and down, whereas pixels are processed left-to-right in each line while lines are scanned top-down (raster processing). The ripple effect can be reduced if every second line is processed in the opposite direction (serpentine processing). You can use the ConfigureProcessingDirection method to obtain an ErrorDiffusionDitherer with serpentine processing mode, which processes even lines left-to-right and odd lines right-to-left.

The following table demonstrates the effect of different processing directions:

Original image
Quantized image

Test image "Cameraman"
Original test image "Cameraman"

Test image "Cameraman" with black and white palette, using Floyd-Steinberg dithering with raster processing
Quantizing with black and white palette and Floyd-Steinberg dithering, using raster processing. The ripple effect is clearly visible on the coat.

Test image "Cameraman" with black and white palette, using Floyd-Steinberg dithering with serpentine processing
Quantizing with black and white palette and Floyd-Steinberg dithering, using serpentine processing. The ripple effect is gone.

  Tip

See the Examples section of the static properties for more examples.

Constructors

ErrorDiffusionDitherer Initializes a new instance of the ErrorDiffusionDitherer class using the specified matrix, divisor and matrixFirstPixelIndex.

Properties

Atkinson Gets an ErrorDiffusionDitherer instance using the filter used by the Apple programmer Bill Atkinson. Uses a 4x3 matrix of only 6 effective values, and propagates only the 75% of the quantization error, which may cause total loss of details of light and dark areas (result may seem under- or overexposed) whereas midtones have higher contrast and preserve details better.
Burkes Gets an ErrorDiffusionDitherer instance using the filter proposed by D. Burkes in 1988. Uses a 5x2 matrix, which is actually the same as the first two lines of the matrix used by the Stucki filter.
FloydSteinberg Gets an ErrorDiffusionDitherer instance using the original filter proposed by Floyd and Steinberg in 1975 when they came out with the idea of error diffusion dithering. Uses a small, 3x2 matrix so the processing is somewhat faster than by the other alternatives.
JarvisJudiceNinke Gets an ErrorDiffusionDitherer instance using the filter proposed by Jarvis, Judice and Ninke in 1976. Uses a 5x3 matrix so the processing is slower than by the original Floyd-Steinberg filter but distributes errors in a wider range.
Sierra2 Gets an ErrorDiffusionDitherer instance using the two-line filter proposed by Frankie Sierra in 1990. Uses a 5x2 matrix so this somewhat faster than the three-line version and still provides a similar quality.
Sierra3 Gets an ErrorDiffusionDitherer instance using the three-line filter proposed by Frankie Sierra in 1989. Uses a 5x3 matrix so this is the slowest Sierra filter but this disperses errors to the furthest among them.
SierraLite Gets an ErrorDiffusionDitherer instance using a small two-line filter proposed by Frankie Sierra. Uses a 3x2 matrix so it has the same performance as the Floyd-Steinberg algorithm and also produces a quite similar result.
StevensonArce Gets an ErrorDiffusionDitherer instance using the hexagonal filter proposed by Stevenson and Arce in 1985. Uses a fairly large, 7x4 matrix, but due to the hexagonal arrangement of the coefficients the processing performance is comparable to a rectangular 5x3 matrix.
Stucki Gets an ErrorDiffusionDitherer instance using the filter proposed by P. Stucki in 1981. Uses a 5x3 matrix so the processing is slower than by the original Floyd-Steinberg filter but distributes errors in a wider range.

Methods

ConfigureErrorDiffusionMode Gets a new ErrorDiffusionDitherer instance that has the specified error diffusion mode.
ConfigureProcessingDirection Gets a new ErrorDiffusionDitherer instance that has the specified processing direction.

Extension Methods

InitializeAsync Gets an IDitheringSession instance potentially asynchronously that can be used to dither the result of the specified IQuantizingSession applied to the specified source. If ditherer is a known ditherer that can be evaluated quickly, then this method might be executed synchronously.
This method is available in.NET Framework 4.0 and above.
(Defined by DithererExtensions)

See Also