Click here to Skip to main content
15,867,686 members
Articles / Multimedia / GDI+
Tip/Trick

Dither - Floyd-Steinberg Dithering

Rate me:
Please Sign up or sign in to vote.
4.50/5 (4 votes)
6 Mar 2014CPOL2 min read 25.8K   1.1K   4   3
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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect MouxIdea Limited
Hong Kong Hong Kong
1981 Born in Hong Kong
1996 Become Badminton Trainer
1997 Hong Kong's Return to China
1998 The Year After Hong Kong's Return to China
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

Comments and Discussions

 
QuestionQuestion about PlusTruncate Pin
John Schroedl11-Sep-15 4:32
professionalJohn Schroedl11-Sep-15 4:32 
GeneralNice work, small correction Pin
John Schroedl11-Sep-15 4:22
professionalJohn Schroedl11-Sep-15 4:22 
Thanks for sharing this.

One small correction is needed to the FormMain.cs so the original looks correct:

Old:
C#
m_Result = FloydSteinbergDither.Process(m_Source, palette.ToArray());


New:
C#
m_Result = FloydSteinbergDither.Process(temp, palette.ToArray());


This way, temp is operated on and not the original.
GeneralSuper work Pin
shankarcrypto6-Mar-14 6:03
shankarcrypto6-Mar-14 6:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.