Phone Vision – 03 Encoding Color

10 01 2011

Last time we learned how to extract the individual color values from a WriteableBitmap.  While this will allow us to analyze the image, we haven’t modified it in any way.  If we want to modify the color of the pixel in a meaningful fashion, we need to revisit the pixel format for a WriteableBitmap.

 

Encoding Color Components

Recall the format for the pixel is

image_thumb4

The assumption here is that we have the separated alpha, red, green, and blue components, but we want to combine them into the ARGB32 pixel format.  So, how do we encode those colors properly?  We can simply left shift each component value the correct number of bits then add them together.  Huh?

What we really want to do is something like this:

image

+

image

+

image

+

image

=

image_thumb4

Another Bitwise Operator

Left Shift

How can we shift the bits into their correct positions?  I bet you know where I’m headed with this – the << (LEFT SHIFT) operator:

operator input shift output
<< 1 1 10
<< 1 2 100
<< 1 3 1000
<< 1 4 10000

It should be relatively easy to see that the appropriate shifts are:

component shift
blue 0
green 8
red 16
alpha 24
 

Using our new found knowledge we can rewrite this as:

int pixel = (alpha << 24) + (red << 16) + (green << 8 ) + blue;

Cake.

 

A Note About Or

Above we used simple addition to combine the shifted color values, however, the traditional technique for combining these is the | (OR) operator.  Here is the table of outputs for |:

operator bit one bit two output
| 0 0 0
| 0 1 1
| 1 0 1
| 1 1 1

How can we use this?  Well, if we | a bit with 0 we get the value of the original bit.  (i.e. 1|0=1 and 0|0=0 – original bit in bold).  This means that we can get the exact same results above with this line of code:

int pixel = (alpha << 24) | (red << 16) | (green << 8 ) | blue;

Why would we want to do this?  My gut says: performance.  In my experimentation, however, it turns out to be pretty minor.  For 100,000,000,000 iterations (that’s 100 billion) it took 17 minutes 48 seconds for the + operation and 17 minutes 33 seconds for the | operation (on my dev machine).  So yes, the | operator is slightly more efficient, but barely.

I use the | version in my code, because image processing is intense and even small performance gains add up when you are looping through hundreds of thousands of pixels.

 

Transparency

It’s important to note that the above code only works correctly for alpha = 255. Since we are working with images this is not typically an issue.  In the next episode we will discuss how to handle transparency.

Summary

Encoding a color from its components is about as easy as we’d expect it to be assuming you understand some fundamentals of computer science.

Download Code

http://cid-88e82fb27d609ced.office.live.com/embedicon.aspx/Blog%20Files/PhoneVision/PhoneVision%2003%20-%20EncodingColors.zip

Up next: Premultiplied Alpha