15,168,633 members
Articles / Multimedia / GDI+
Tip/Trick
Posted 6 Mar 2014

22.9K views
4 bookmarked

# Dither - Floyd-Steinberg Dithering

Rate me:
Dither - Floyd-Steinberg Dithering

## Introduction

I searched a lot about Dithering from our best friend Google, but I couldn't find any sample code which converts a true color into dithered color. But it's very useful in many ways, so I wrote this hoping it can help people who need it. BUT someone said if I removed the image and code, my article has nothing to read. So I decided to remove the sample image and code, please try to download the source and try it, it's nice.

## Background

### What is dithering?

A typical use of dither is: given an image in grey-scale, convert it to black and white, such that the density of black dots in the new image approximates the average level of grey in the original image. In other words, a grey-scale image is made by black(0x000000) and white(0xffffff).

Floydâ€“Steinberg dithering is an image dithering algorithm first published in 1976 by Robert W. Floyd and Louis Steinberg. It is commonly used by image manipulation software. Read more.

Since I'm not writing a research document, I skip describing the details here.

## Using the Code

Not much, just three core functions.

• `PlusTrancate`, `FindNearestColor` and `Process`.
• `PlusTrancate` tries to add a quantization error into an existing color and prevent the color over flow, as maximum number is 255.
• `FindNearestColor` is the nearest color, you need to pass the palette into this function to find the mapping that you are looking for.

e.g.

• [ { 0, 0, 0 }, { 255, 255, 255 } ] means looking for Black and White
• [ { 255, 0, 0 }, { 0, 255, 0 }, { 0, 0, 255 } ] means looking for RGB
• [ { 0, 255, 255 }, { 255, 0, 255 }, { 255, 255, 0 } ] means CMY

The core function `Process` for each pixel of the image then gets the nearest color from that pixel, and calculates the quantization error from the surround color, to make image become more representative.

The quantization error calculates here:

 * 7/16 3/16 5/16 1/16

Point of Interest

Except Floyd-Steinberg, there are still some algorithms for dither, e.g. Jarvis, Judice, and Ninke dithering, Stucki dithering, Burkes dithering. However, I can only find something described for Floyd-Steinberg.

## History

• 6th March, 2014: Initial post

## Share

 Architect MouxIdea Limited Hong Kong
1981 Born in Hong Kong
1999 The Year Before Millennium
2000 First touch of programming - ASP(guestbook)
2001 Outstanding Student Award - Computing Department
2002 Xcellence Developer Awards - Best Graphical Focused Application(Game) Award
2003 Microsoft MVP - .NET
2004 Be lost in Technology
2005 Microsoft MVP - C#
2006 Microsoft MVP - C#
2007 Getting Marry - Cheers~
2008 Microsoft MVP - C#
2009 Microsoft MVP - C#
2010 Microsoft MVP - C#
2011 Start my software hut

http://www.csharpfans.com

http://www.bugyiu.com

http://www.mouxidea.com

 Since a is a byte, there is no need for "& 0xff", right? C#Copy Code ```public static byte PlusTruncate(byte a, int b) { if ((a & 0xff) + b < 0) return 0; else if ((a & 0xff) + b > 255) return (byte)255; else return (byte)(a + b); } ```