OpenSource Image Dithering for AS3. (demo+source).

Intro

As promised in my previous post, here’s a small opensource project from my side. It’s tiny, really, but I hadn’t seen an ActionScript implementation of any form of Image dithering before.

Dithering….what ?

Just a brief explanation what dithering in this context means. From wikipedia :

Dither is an intentionally applied form of noise, used to randomize quantization error, thereby preventing large-scale patterns such as contouring that are more objectionable than uncorrelated noise.”

Words to take note of in that sentence are quantization, and “intentionally applied form of noise”. In our case quantization is the removal or swapping of colors. The form of noise applied differs over the several implementations and in so called “ordered dithering” it’s hardly noise, rather a carefully chosen threshold matrix.

Dithering, why ?

Dithering imagery has been around for some time. Put a close eye to any black and white printed newspaper’s pictures and you’ll see the effect.

It’s basically been around a lot longer then I have in my 28 years of life…that’s for sure. I first learned terms like “ordered dithering” and “Floyd-Steinberg Error Diffusion” in my young and early days on the Amiga hardware. See, in those days computer hardware wasn’t capable of displaying the huge arrays of colours like now-a-days. Since you then had few colours to spare (a typical amiga workbench ran at 16 to 128 colours or so), you needed to be creative to get yourself a nicely pimped desktop image, whilst still sparing colours for your icons.

A better example of a dithering implementation for our industry is probably that checkbox when you want to save for web in Photoshop, using GIF. Or when you print something on a pure black and white printer.

Conclusion; dithering is normally used to create the illusion of tones on a device which is otherwise not capable of displaying it. So why port this to our ARGB/32Bit enabled Flash Player ? Part of the reason why I worked on this is because I just like the aesthetic of the effect. It just brings back wonderful memories of pimping my Amiga desktop.

Dithering in AS3

So, the algorithms for dithering are really quite simple. I was playing around with hydra Pixel Bender and had some ideas on converting some old algorithms to have them run in realtime. Then I thought I could make this run in realtime on Flash 9. So, first I did a version of the Algo in pure AS3. I played around with converting it to something fast enough to run at at least 20 frames per second on an average machine…and painfully failed. The remains are the AS3 version (hydra Pixel Bender version still in progress)….and I decided to clean that up a bit, and have it released as an OS project for anyone to use.

Currently it only contains so-called error-diffusion based ditherers. They make the most sense anyway, since the ordered ditherers really have nasty visual sideeffects, like Bayer’s crosshatches. Check the variants out in this little demo application using the class.

The Demo : try and use “No Dithering” first to see the effects of regular palette conversion.

The Source

Usage :

ImageDithering.dither(bitmapData, type, levels, grayscale);

Where :

BitmapData is the image to be manipulated.

Type is the form of dithering, currently supported :

  1. ImageDitheringType.FLOYD_STEINBERG
  2. ImageDitheringType.FALSE_FLOYD_STEINBERG
  3. ImageDitheringType.STUCK
  4. ImageDitheringType.NO_DITHER

Levels is the amount of colour levels to quantize to per channel.

Grayscale is a boolean indicating whether to convert the image to grayscale before the process is ran.

Right click and viewsource on the example to see how it’s implemented in Flex.

Quick update : Mario Klingemann, working on Aviary’s Peacock did a quick test with it. My effort had some use anyway!

This entry was posted in Examples, Flash, Flex, News and tagged , , , , , . Bookmark the permalink.

15 Responses to OpenSource Image Dithering for AS3. (demo+source).

  1. Great job – works smoothly in Peacock already.

    Just as an idea – how about adding the option to provide a custom color palette?

    I haven’t tried it, but it might speed up your code event a little bit more if you use paletteMap first to do the quantization – here’s a posterization code from Peacock:

    var levels:Number = __parameters.getValue(“levels”);
    var r:Array = [];
    var g:Array = [];
    var b:Array = [];
    var a:Array = [];

    var vStepF:Number = 255 / levels;
    var vStep:int = 0.5 + vStepF;
    var v:int = 0;
    for (var i:int = 0;i255) v=255;
    a[i] = v << 24;
    r[i] = v << 16;
    g[i] = v << 8;
    b[i] = v;
    }

    output.paletteMap(output,output.rect, origin,r,g,b,__parameters.getValue(“posterizeAlpha”) ? a : null);

    • UnitZeroOne says:

      Good to hear it had some use ;-)

      Posterization through paletteMap is implemented for the NO_DITHER mode…but…and here’s where I stumbled upon trying to “filterize+blendmode” the whole thing…these error diffusion kernels iteratively add to the image per pixel…the kernel runs from top left to bottom right and adds to pixels in between, finding the best color for them after they have been error-diffused….so far I haven’t come up with a blendmode + filter solution yet.

  2. Oh yes of course – now I see it. Well, that makes it indeed difficult to impossible to use paletteMap here. BTW – it looks like my code above was garbled by html.

  3. Sorry for nagging but I have a tiny cosmetic issue: I think the correct way to pick just black and white would be to say “2 Levels” and not “1 Level” as it is currently implemented. To me “1 Level” would be just one color aka black.

    • UnitZeroOne says:

      You’re right. I was actually also still thinking about that one….I didn’t want to go all out on this, but really what it should have is some kind of ImageFormat class, to specify the bits per channel and amount of channels. Not sure…2 levels is probably the best approach now, I’ll check it in ….

  4. Hi,

    Great stuff,

    I’ve done a similar experiment back in February and posted something in March.
    When I say pretty similar, I’m not kidding :)

    http://tomaterial.blogspot.com/2008/03/dithering-in-actionscript-30.html

  5. Oh thanks! Since I use AS3 I got to learn some things again. I already forgot that I´ve dithered in AS2 already.

  6. Pingback: import.labs*

  7. Michael says:

    Cool!

    We did some pattern dithering a year back on this site:

    http://www.firstinflight.com.au

    The nice thing about it is most of the backgrounds are 20kb jpgs which the dithering nicely hides.

  8. Brian says:

    Is it possible to use this to do floyd-steinberg dithering into a pre-defined palette of 256 colors?

  9. Jonathan Dumaine says:

    Interesting, do you think this could be used for gradients or Sprites with small difference in colors to reduce banding?

  10. @Mario: I instantly thought about palette mapping, too. However, it should be perfectly legitimate to quantize to a particular number of colors, then to map to a given palette afterward. There are a couple of examples of color matching from a given palette on the web (I’ve seen one somewhere).

  11. Pingback: Basic dithering « yeuchi

  12. Anthony says:

    Hi, Ralph, I noticed that you wrote this long time ago. Now there’s a new mothod in Flash player 11.3+, use bitmapdata.lock() before pixel manipulation, and then invoke bitmapdata.unlock(), I tried to add these in your dithering function, it’s much faster .

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Notify me of followup comments via e-mail. You can also subscribe without commenting.