【问题标题】:What does this java method do with bitwise operations?这个 java 方法对按位运算有什么作用?
【发布时间】:2011-11-01 12:14:13
【问题描述】:

我不熟悉按位运算。这是一种图像处理算法。发生了什么?

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? 为什么如果灰度

【问题讨论】:

    标签: java image-processing binary bitwise-operators


    【解决方案1】:

    0xff 等的 & 操作应用位掩码。这是一个按位和运算。由于 Java 中的 int 是 32 位的,因此您可以将 0xff 读取为 00000000_00000000_00000000_11111111,将 0xff00 读取为 00000000_00000000_11111111_00000000 等等。他们只是省略了前导零。

    因此,如果您执行pixels[i] &amp; 0xff,您会得到一个 int,其中最后 8 位与以像素 [i] 为单位相同,其余位设置为零。

    &gt;&gt; 运算符是右移。它将在指示的位数上将位模式向右移动。如果b 包含00110011_11001100_00010110_01001100 并且你做了b &gt;&gt; 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。

    那么这实现了什么?嗯,它基本上归结为像素[i] 的前 8 位被忽略,接下来的 3 段 8 位分别被解释为 0 到 255 之间的单个值,取其平均值。

    然后根据 128 检查该结果。如果它较低,pixel[i] 我设置为 0xff000000,否则设置为 0xffffffff。

    这是您在对编码为整数的颜色进行操作时遇到的典型的小玩意。这可能是 argb 方案,其中 int 的前 8 位是 alpha(透明度),接下来的 8 位是红色,接下来的 8 位是绿色,最后 8 位是蓝色。或其变体。 0xff000000 是完全不透明的黑色,而 0xffffffff 是完全不透明的白色。

    【讨论】:

    • +1,很好的答案!对于对按位运算不太了解的人! :-)
    【解决方案2】:

    它的作用取决于颜色模型以及颜色在内存中的表示方式。

    我的猜测是它将普通的 ARGB 图像转换为基于 50% 阈值的黑白图像。 (使“亮度”低于 50% 的所有像素完全变黑,而所有其他像素完全变白。)

    (pixels[i] &amp; 0xff00 &gt;&gt; 8) 做了什么?

    • pixel[i]你已经知道了:-)
    • &amp; ff00 屏蔽掉第二个字节中的位
    • &gt;&gt; 8 移动位向右,八个位置(即使最右边的字节下降到边缘)

    什么是0xff00

    0xff00 是值 65280 的十六进制文字(或二进制的 1111111100000000)

    为什么如果灰度

    这一行:

    int gray = ((pixels[i] & 0xff) +
                ((pixels[i] & 0xff00) >> 8) +
                ((pixels[i] & 0xff0000) >> 16)) / 3;
    

    将红色、绿色和蓝色分量相加并除以三(求平均值)。

    这一行

    pixels[i] = gray < 128 ? 0xff000000 : 0xffffffff;
    

    大概是说如果灰度小于一半,像素应该是全黑的,否则应该是全白的。

    【讨论】:

    • +1: 0xff000000 表示其黑色且不透明,假设其 ARGB 而不是 RGB 格式。
    【解决方案3】:

    (pixels[i] & 0xff) = 蓝色值在 0 到 255 之间

    (pixels[i] & 0xff00) >> 8 = 0 到 255 中的绿色值

    (pixels[i] & 0xff0000) >> 16) = 0 到 255 中的红色值

    然后你取上面找到的 3 个值的平均值。

    然后根据灰度,将其设为白色或黑色,即低于 50% 的灰色为黑色,否则为白色。

    【讨论】:

      【解决方案4】:

      (pixels[i] &amp; 0xff00) &gt;&gt; 8 从 int 中取出第二个字节,表示绿色 - &amp; 使除 8-15 零之外的所有位和 &gt;&gt; 将它们向右移动 8 位,所以如果数字是(以位为单位)0101000100001100:

      0101000100001100 & 0xff = 0101000100001100 & 1111111100000000 = 0101000100000000.
      0101000100000000 >> 8 = 01010001
      

      ((pixels[i] &amp; 0xff0000) &gt;&gt; 16) 也一样。

      不,您取它们的平均值 (/3) 并获取颜色是更接近白色还是更接近黑色 (gray &lt; 128)。根据这一点,您可以将像素设置为黑色或白色。

      【讨论】:

        【解决方案5】:

        0xFF00 它是一个位掩码,表示二进制表示的 1111111100000000。

        因此,当您将此掩码应用于数字时,您留下了高 8 位。

        运算符>>表示右移。例如 11110000 >> 2 = 00111100

        【讨论】:

          猜你喜欢
          • 2020-11-20
          • 1970-01-01
          • 2011-05-30
          • 2023-04-06
          • 2014-07-23
          • 2013-05-28
          • 1970-01-01
          • 2018-09-04
          相关资源
          最近更新 更多