Friday 28 November 2008

That shouldn't be too hard

The other day I was reading about the new Windows 7 task bar, specifically the new Colour Hot-track that is available on mouse over. For those that don't know what this is here is a description straight from the horses mouth:

Color Hot-track

Color hot-track is a small touch that typifies the new taskbar’s personality. When a person moves her mouse over a running program on the taskbar, she will be pleasantly surprised to find that a light source tracks her mouse and the color of the light is actually based on the icon itself. We calculate the most dominant RGB of the icon and dynamically paint the button with this color. Color hot-track provides a delight factor, it offers feedback that a program is running and it showcases a program’s icon. We’ve always believed that programs light up the Windows platform and now, we’re returning the favor.

Windows 7 Color Hot-track

Fig 9. Color Hot-track: moving the mouse across a running window reveals a dynamically colored light effect

Now I may be wrong but I thought this looked pretty cool and at first glance thought that it wouldn't be too hard to do.

The first step would be to work out how to find the dominant colour of an icon. There are many approaches that I went through to accomplish this, a lot of them were very complex and not particularly good until finally it occurred to me that GIF compression already does a lot of the work for you; it takes a full colour image and reduces the colour set down to the 256 colours that best represent the content. Tracing through the GIF ImageIO writer code I discovered the com.sun.imageio.plugins.common.PaletteBuilder class that does the colour reduction following an "octree quantization method". With a small amount of modification this class does everything needed to reduce the image colours down to a reasonable number, as a bonus it also counts the pixels that contribute to each colour as it goes.

So now I have this reduced set of colours, say 6 colours that make up the image, all I need to do is return the colour with the most pixels that contributed to it, right? While this may be technically correct there are also a few other factors that our eyes seem to take into account, like the vividness of the colour or how bright it is.

Take the above image as an example, if you were to ask anyone what the dominant colour of the image is they would probably say blue, when in fact there is more white there than blue. To cater for this case I needed to take the actual colour into account and weigh the pixel count against factors like saturation and brightness to give a more accurate representation of what a human would say.

So from an initial idea that it would be fairly easy to find the dominant colour of an image I ended up with the following process:
  1. Reduce the image down to 6 colours using octree quantization
  2. Go through each of the 6 colours finding the colour that gets the highest score when weighed using the following algorithm:
weight = numPixelsOfColour +
(numPixelsOfColour * saturation * 1.1) +
(numPixelsOfColour * brightness * 0.8)

Where saturation and brightness are taken from the HSB representation of the colour.

I'll leave you with a simple demo so that you can see what the dominant colour of your own images are. You can get the source from the subversion repository of the scalableicons project.

In the next post I'll try to implement the glowing effect using this dominant colour to try and imitate the hot-track effect.

No comments:

Post a Comment