使用Javascript从非钳位阵列有效地生成钳位阵列

时间:2017-06-20 18:22:45

标签: javascript jquery arrays

我有一些比较两个图像的代码。要获取图像的画布数据,我使用:

 const canvasOneImageData = canvasOneContext.getImageData(0, 0, canvasOne.width, canvasOne.height);

我的目标是构建一系列rgba Uint8ClampedArrays来表示此缓冲区中的每个像素。我目前使用以下内容:

const canvasOneBuffer = new Uint8Array(canvasOneImageData.data.buffer);
// within an x/y loop:
const newPixel1Data0 = canvasOneBuffer[4 * (x + y * canvasOne.width) + 0]; // r
const newPixel1Data1 = canvasOneBuffer[4 * (x + y * canvasOne.width) + 1]; // g
const newPixel1Data2 = canvasOneBuffer[4 * (x + y * canvasOne.width) + 2]; // b
const newPixel1Data3 = canvasOneBuffer[4 * (x + y * canvasOne.width) + 3]; // a
const pixel1Data = new Uint8ClampedArray(4);
pixel1Data[0] = newPixel1Data0;
pixel1Data[1] = newPixel1Data1;
pixel1Data[2] = newPixel1Data2;
pixel1Data[3] = newPixel1Data3;

但这似乎有些迟钝。有没有什么方法可以创建新的Uint8ClampedArray(4);,只需从缓冲区数组中读取一次并对新数组进行单次写入?

我知道我可以使用canvasOneBuffer.slice(0, 4) - 但这仍然需要一个零碎的夹紧阵列组合。性能是最重要的,因为这将每秒进行数百次。

1 个答案:

答案 0 :(得分:1)

var pixelData=canvasOneImageData.data;

图像数据已经是js中的钳位数组。我认为最好以四个字节迭代它:

for(var i=0;i<pixelData.length-3;i+=4){
  var pixel1=pixelData[i];
  var pixel2=pixelData[i+1];
  var pixel3=pixelData[i+2];
  var pixel4=pixelData[i+3];
  //...
}

如果您真的想要子阵列,可以使用 TypedArray.prototype.subarray

var pixel1Data=canvasOneImageData.data.subarray(0,4);

请注意,这涉及到相同的缓冲区。因此性能非常高,但它不是副本,因此修改也会修改图像。如果你不想要这个,可以使用 .slice

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/subarray