使用 Javascript 从非夹紧数组高效生成夹紧数组



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

 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) - 但这仍然需要一个零碎的夹紧阵列组合。 性能是这里的首要任务,因为这每秒将完成数百次。

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

最新更新