我不熟悉按位运算。这是一种图像处理算法。发生了什么事?
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;
}
}
我发现 (pixels[i] & 0xff) 只是以某种方式“归一化”并让像素/字节成为 0..255 之间的正值。
(pixels[i] & 0xff00 >> 8) 是做什么的?
什么是 0xff00?
为什么如果 gray < 128 像素变为 0xff000000 或者 0xffffffff?
最佳答案
0xff
等的 & 操作应用位掩码。这是一个按位和操作。由于 Java 中的 int 是 32 位的,您可以将 0xff
读取为 00000000_00000000_00000000_11111111
,将 0xff00
读取为 00000000_00000000_11111111_00000000
等等在。他们只是省略了前导零。
因此,如果您执行 pixels[i] & 0xff
,发生的情况是您得到一个 int,其最后 8 位与 pixels[i] 中的相同,其余位设置为零。
>>>
运算符是右移。它会将位模式向右移动指定的位数。如果 b
包含 00110011_11001100_00010110_01001100
而您执行了 b >> 8
,您将得到 00000000_00110011_11001100_00010110
。最后 8 位“掉落”,而左边的零已移入。我不记得如果前导位为 1,此操作是否会向左移 1,所以也许有人可以确认或否认这一点。
了解了这一点,让我们来看看这一行:
int gray = ((pixels[i] & 0xff) + ((pixels[i] & 0xff00) >> 8) + ((pixels[i] & 0xff0000) >> 16)) / 3;
这里发生的是我们创建一个 int 如下(不是确切的代码执行顺序,只是为了说明):
- pixels[i] 被屏蔽,因此只保留最后 8 位,其余变为 0。
- pixels[i] 被屏蔽,因此仅保留位 8 - 15(从右到左计数,从 0 开始),其余变为 0。然后将结果向右移动 8 位。如果我们从 00001111_00001111_10101010_00110011 开始,结果将是 00000000_00000000_00000000_10101010。
- pixels[i] 被屏蔽,因此仅保留位 16 - 23,然后向右移动 16 位。
- 将以上三个操作的结果相加并...
- 该结果除以 3。
那么这实现了什么?好吧,它基本上归结为 pixels[i] 的前 8 位被忽略,接下来的 3 个 8 位部分分别被解释为 0 到 255 之间的单个值,取其平均值。
然后根据 128 检查该结果。如果它较低,则 pixels[i] 我设置为 0xff000000,否则设置为 0xffffffff。
这是您在对编码为整数的颜色进行操作时遇到的典型问题。这可能是 argb 方案,其中 int 的前 8 位是 alpha(透明度),接下来的 8 位是红色,接下来的 8 位是绿色,最后 8 位是蓝色。或其变体。 0xff000000 是完全不透明的黑色,而 0xffffffff 是完全不透明的白色。
关于java - 这个java方法对按位运算有什么作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7966241/