解释按位运算符在canvas imagedata像素颜色赋值中的使用

时间:2014-10-18 18:52:01

标签: javascript bitwise-operators

首先代码:

    data[y * canvasWidth + x] =
        (255   << 24) | // alpha
        (value << 16) | // blue
        (value <<  8) | // green
         value;     // red
    }

我试图重新理解这一点,我曾经有过。但后来我忘记了。我在本文中再次找到了它:https://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-ty

此代码正在使用中:http://jsfiddle.net/andrewjbaker/Fnx2w/

我的问题:

  • 什么&lt;&lt;和|做到这里,他们做了什么以及为了什么?
  • 如何将所有rbga值组合在一起工作?

链接:

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays
  2. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray
  3. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array
  4. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
  5. https://developer.mozilla.org/en-US/docs/Web/API/ImageData

1 个答案:

答案 0 :(得分:5)

代码尝试将值打包为32位。试着像这样理解

(255 << 24) | (value << 16) | (value << 8) | value;

首先,255左移24次。所以,二进制值就像这样

1111 1111 0000 0000 0000 0000 0000 0000

然后,无论value的值是什么,左移16,然后or加上已经获得的值。让我们假设value也是255.所以,255&lt;&lt; 16将是

0000 0000 1111 1111 0000 0000 0000 0000

因此,当我们按位or时,值变为

1111 1111 1111 1111 0000 0000 0000 0000

现在,我们在其中打包了两个值。同样,所有值都将打包为32位数字。


简单包装是故事的一半。如果我想获得REG值怎么办?我们使用掩码和按位AND运算符,就像这样。

(colorValue & (255 << 24)) >> 24

这将给出8位红色值。我们只是在32位数字中启用最右边的8位,而所有其他都设置为0.因此,当我们使用实际值执行&时,我们将在与掩码相对应的那8位中启用位。然后我们右移24,将24位推离边界,只剩下实际的红色值。

同样,您可以获得绿色值,例如

(colorValue & (255 << 16)) >> 16

和蓝色

(colorValue & (255 << 8)) >> 8

和简单的

的最后一个值
(colorValue & 255)

实施例

让我们说,

var colorValue = 2131637306;

位表示是

0111 1111 0000 1110 0011 0100 0011 1010

所以,当我们做

console.log(colorValue & (255 << 24));
# 2130706432

,其二进制表示为

0111 1111 0000 0000 0000 0000 0000 0000

当我们做的时候

console.log((colorValue & (255 << 24)) >> 24);
# 127

二进制表示是

 0000 0000 0000 0000 0000 0000 0111 1111

同样,可以检索所有值。

正如@GameAlchemist在评论部分提到的那样,掩码通常用HexaDecimal表示,以便清楚地理解这一点,就像这样

var redMask   = 0xFF000000,
    greenMask = 0x00FF0000,
    blueMask  = 0x0000FF00,
    valueMask = 0x000000FF;