我有一些比较两个图像的代码。 为了获取图像的画布数据,我使用这个:
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