我有一些比较两个图像的代码。要获取图像的画布数据,我使用:
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)
- 但这仍然需要一个零碎的夹紧阵列组合。性能是最重要的,因为这将每秒进行数百次。
答案 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