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
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:
+
+
+
=
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
Up next: Premultiplied Alpha
[…] Up next: Encoding Color […]
[…] Previously we explored encoding pixels from color components. This works perfectly if our alpha value is 255, and in most cases it will be. But, what if we need transparency? […]
[…] elements in either of two sets. If you have been playing along, this is very similar to the | (binary OR) operation mentioned in lesson three. Below we union the puzzle set with the set of its complement. The output is the […]