【问题标题】:explain the bitwise opeartors use in canvas imagedata pixel color assignment解释画布图像数据像素颜色分配中使用的位运算符
【发布时间】:2014-10-18 18:52:00
【问题描述】:

首先是代码:

    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/

我的问题:

  • 如何将所有 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

【问题讨论】:

  • 它可以让您将 4 个数字放入一个整数中,因此结果数组的长度是 1/4。这可以使某些操作更快,并减少图像数据的占用空间。

标签: javascript bitwise-operators


【解决方案1】:

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

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

首先,255 左移 24 次。于是,二进制值变成了这样

1111 1111 0000 0000 0000 0000 0000 0000

然后,无论value 的值是多少,左移16 位,然后or 与已经获得的值一起移动。让我们假设value 也是 255。所以,255

0000 0000 1111 1111 0000 0000 0000 0000

所以,当我们按位进行or 时,值变为

1111 1111 1111 1111 0000 0000 0000 0000

现在,我们在其中打包了两个值。同样的方式,所有的值都会被打包成一个 32 位的数字。


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

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

这将给出 8 位红色值。我们只启用 32 位数字中最右边的 8 位,所有其他位设置为 0。因此,当我们使用实际值执行 &amp; 时,我们将启用与掩码对应的这 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 在 cmets 部分中提到的那样,掩码通常用 HexaDecimal 表示,以便清楚地理解这一点,就像这样

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

【讨论】:

  • 响亮而清晰,但是对于'read'部分,我发现更清晰,如果js引擎很愚蠢,使用red = colorValue & 0xFF0000; 会更快;绿色=颜色值 & 0x00FF00;蓝色 = colorValue & 0x0000FF
  • @GameAlchemist 谢谢 :-) 包括在答案中。
  • 为了清楚和完整,您能否解释一下这种包装如何与画布相匹配...ctx.getImageData(0,0,w,h).data 返回数据视图类型为Uint8ClampedArray。那么Uint32Array类型化的dataView是用来存储数据的。那么它们有什么区别呢?
  • @MuhammadUmer :您可以在字节缓冲区上拥有任何类型的视图:您可以将它们视为 8,16、32 位有符号或无符号整数数组 + 32/64 浮动视图 + 钳位看法 。有关类型化数组,请参阅本教程,来自 html5rocks:html5rocks.com/en/tutorials/webgl/typed_arrays
  • !!!重要提示!!!如果在图像字节缓冲区上使用 32 位视图,则要考虑字节序,为了缩短它,您必须反转 rgba 掩码顺序(它在 99.99999% 的设备上是 abgr)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-24
  • 1970-01-01
  • 2014-08-15
相关资源
最近更新 更多