Im not familiar with bitwise operations. This is an image manipulation algorithm. What is happening?
void binarize50(int pixels[]) {
for(int i = 0; i < pixels.length; i++) {
int gray = ((pixels[i] & 0xff) + ((pixels[i] & 0xff00) >> 8) + ((pixels[i] & 0xff0000) >> 16)) / 3;
pixels[i] = gray < 128 ? 0xff000000 : 0xffffffff;
}
}
I found out that (pixels[i] & 0xff) just “normalizes” somehow and let the pixel/byte become a positive value between 0..255.
What does (pixels[i] & 0xff00 >> 8) do?
What is 0xff00?
And why if grey < 128 the pixel becomes 0xff000000 or else 0xffffffff?
The & operation with the
0xffand the like applies a bitmask. It’s a bitwise and operation. Since an int in Java is 32-bit, you can read0xffas00000000_00000000_00000000_11111111,0xff00as00000000_00000000_11111111_00000000and so on. They just omit the leading zeroes.So if you do
pixels[i] & 0xff, what’s happening is that you get an int of which the last 8 bits are the same as in pixels[i] with the remaining ones set to zero.The
>>operator is the right shift. It will shift the bit pattern to the right over the number of bits indicated. Ifbcontained00110011_11001100_00010110_01001100and you didb >> 8, you’d end up with00000000_00110011_11001100_00010110. The last 8 bits “dropped off”, while to the left zeroes have been shifted in. I don’t remember if this operation will shift in 1’s to the left if the leading bit was 1, so maybe someone can confirm or deny that.Knowing this, let’s take a look at this line:
What happens here is that we make an int as follows (not exact code execution order, just for illustration):
So what does this achieve? Well, what it basically comes down to is that the first 8 bits of pixels[i] are ignored, and the following 3 sections of 8 bits are each interpreted as a single value between 0 and 255 of which the average is taken.
Then that result is checked against 128. If it’s lower, pixels[i] i set to 0xff000000, otherwise it’s set to 0xffffffff.
This is typical bit twiddling you’d encounter in operations on colors coded as ints. This is probably the argb scheme, where the first 8 bits of an int are the alpha (transparency), the next 8 bits are red, the next 8 are green and the last 8 bits are blue. Or a variant thereof. 0xff000000 would be completely opaque black, while 0xffffffff is completely opaque white.