Reputation: 615
I know that to get colour values from rgb you use
b = rgb >> 0
g = rgb >> 8
r = rgb >> 16
Could someone explain why this works? Each of those is 8 bits right? Doesn't >> n give the first n bits? How does it work for b and r as well?
Upvotes: 0
Views: 1332
Reputation: 110506
Yes, these are the "Right Shift" operators - so, if the Color number is encoded in 24bits, being the higher 8 bit for the red color, the middle 8 bit for green and the lower 8 for Blue, something as above might work.
For example, the Orange color encoded as 0xff8000;
doing:
rgb = 0xff8000;
b = rgb >> 0; // redundant, the ">>" operator shuld not have been used at all
g = rgb >> 8 ; // g contains ff80
r = rgb >> 16 ; //r contains ff
What happens here that it might work with just these operators is that the r,g and b variables are defined as 8 bit unsigned ints, in a way the upper bits (like the g above) get truncated. I don't think that is a good practice, as it will depend on specific semantics and correct variable types to hold just 8bit unsigned. The following variant explicitly filters out the higher bits using the bitwise AND operator (&), so that one gets the color components for any size of r, g and b variables, and should be preferred, since it won't cause exactly the doubt that lead you to ask this question:
rgb = 0xff8000;
b = rgb & 0xff;
g = (rgb >> 8) & 0xff ; // g contains 80
r = (rgb >> 16) & 0xff ; //r contains ff
Upvotes: 2
Reputation: 882116
Actually that shouldn't work unless you strip off the unneeded bits at some point.
>>
is the right shift operator, where zero-bits feed in from the left and bits rolling off the right are sent to the bitbucket (discarded). Consider that a 24-bit RGB value has the following bits, eight per color):
rrrrrrrrggggggggbbbbbbbb
Right-shifting that by 0 bits gives you the same value, right-shifting it by eight bits gives you rrrrrrrrgggggggg
, and right-shifting by sixteen bits gives rrrrrrrr
.
So you can see that the three shifts give you each of the three color values in the "lower" (rightmost) eight bits. A more canonical way to do this would be to and
it with 255 (0xff
in hex) to ensure all but the lower eight bits are cleared to zero:
b = (rgb ) & 0xff;
g = (rgb >> 8) & 0xff;
r = (rgb >> 16) & 0xff;
See this answer for a more detailed description of the bitwise operators.
Upvotes: 4
Reputation: 50026
suppose rgb is: 0xFF55FF which in binary is:
11111111 01010101 11111111
^^^^^^^^ ^^^^^^^^ ^^^^^^^^
r g b -- rgb color parts (or components)
now what your code is doing is extracting each of those components by shifting to right, I assume that r,g,b are of unsigned char
type (otherwise it would not work):
b = rgb >> 0
here there is no need to shift, rgb vale is implicitly casted to unsigned char which leaves only 11111111 - b part.
g = rgb >> 8
here, firstly b part is shifted right so that g part is on its place, and again as above 01010101 binary part is assigned to g, if g is one byte then during assignment it is implicitly casted (r part is casted away) and g is assigned 01010101 binary value.
r = rgb >> 16
here is the same history as in case of g
Upvotes: 2
Reputation: 24630
You should add the types:
int rgb = 0x1234FF;
byte b = rgb >> 0;
byte g = rgb >> 8;
byte r = rgb >> 16;
Then it gets a little bit clearer. The bits of rgb get shifted to the right and by assign to a byte
all beyond the 8th bit get truncated.
Upvotes: 1