I am trying to understand the code below where b
is a given integer and image开发者_JS百科
is an image.
I understand that if the RGB value at given point i,j is greater than b then set that pixel to white else set to black. so would convert the image into black and white.
However I am lost to what (& 0xff) actually does, I am guessing its a kind of binary shift?
if ((image.getRGB(i, j) & 0xff) > b) {
image.setRGB(i, j, 0xffffff) ;
} else {
image.setRGB(i, j, 0x000000);
}
It's a so-called mask. The thing is, you get the RGB value all in one integer, with one byte for each component. Something like 0xAARRGGBB (alpha, red, green, blue). By performing a bitwise-and with 0xFF, you keep just the last part, which is blue. For other channels, you'd use:
int alpha = (rgb >>> 24) & 0xFF;
int red = (rgb >>> 16) & 0xFF;
int green = (rgb >>> 8) & 0xFF;
int blue = (rgb >>> 0) & 0xFF;
In the alpha case, you can skip & 0xFF
, because it doesn't do anything; same for shifting by 0 in the blue case.
The
& 0xFF
is getting one of the color components (either red or blue, I forget which).
If the color mask is not performed, consider RGB (0, 127, 0), and the threshold 63. The getRGB(...) call would return
(0 * 256 * 256) + (127 * 256) + 0 = 32512
Which is clearly more than the threshold 63. But the intent was to ignore the other two color channels. The bitmask gets only the lowest 8 bits, with is zero.
The
> b
is checking if the color is brighter than a particular threshold, 'b'.
If the threshold is exceeded, the pixel is colored white, using
image.setRGB(i,j,0xffffff)
... otherwise it is colored black, using
image.setRGB(i,j,0x000000)
So it is a conversion to black and white based on a simple pixel-by-pixel threshold on a single color channel.
Color representation
The RGB value is an integer so it is represented in memory by 4 bytes (or equivalently 32 bits).
Example:
00000001 00000010 00000011 00000100
Each byte represents one component of the color :
- 1st byte: alpha value (00000001 in the example) which corresponds to the opacity
- 2nd byte: red value (00000010 in the example)
- 3rd byte: green value (00000011 in the example)
- 4th byte: blue value (00000100 in the example)
0xff and 0xffffff symbols
0xff represents the hexadecimal value FF which is equal to the integer 255. Its binary representation is:
00000000 00000000 00000000 11111111
Similarly 0xffffff is represented by:
00000000 11111111 11111111 11111111
It corresponds to the color white (red, green and blue equal to 255).
& operator
The binary operator and "&" is applied on two integers i1 and i2 (i1 & i2). It returns an integer with all its bits equal to 0 except the ones which are equal to 1 in both i1 and i2. For example, if we apply & on my first example and on 0xff, we obtain:
00000000 00000000 00000000 00000100
As a consequence, (& 0xff) enables to only keep the values of the last byte (i.e., the value of the blue component of the color).
// If the blue component of image.getRGB(i, j) is greater than b
if ((image.getRGB(i, j) & 0xff) > b) {
// Set the image to white
image.setRGB(i, j, 0xffffff) ;
} else {
// Set the image to black
image.setRGB(i, j, 0x000000);
}
It is probably because there is some conversion to or from ARGB. This is a really good blog post about why to do bit-wise operations for colors.
& 0xff
is a bitwise AND
(image.getRGB(i,j)&0xff)
gets the blue value of the rgb encoded int returned by getRGB
the > b
part check whether it's larger than some threshold
精彩评论