为什么图像数据没有参考?

时间:2015-09-19 07:32:14

标签: javascript performance canvas getimagedata putimagedata

是的,我知道.getImageData()

我的意思是,我要说,我必须改变一些像素:

var imageData = ctx.getImageData(...);

似乎,这种方法给了我全新的“真实”(隐藏在我身边的地方)图像数据。 我这样说,因为如果你创造一个新的:

var imgData2 = ctx.getImageData(.../*same parameters as before*/);

并比较两个缓冲区:

imageData.data.buffer === imgData2.data.buffer; //false

因此,每次从它的位图创建新副本。哦,天哪,为什么?好的,走得更远:

/*...apply some new changes to the imageData in a loop...*/

上面没什么特别的。但是现在,是时候把它放回去了:

ctx.putImageData(imageData, ...);

这个内部本身运行新循环并复制我的imageData。

这么多额外的工作!有没有办法获得实际的imageData并在没有get / put的情况下操作它?如果不是 - 我再问一次 - 为什么?这是安全原因吗?他们害怕我能用这些像素做什么?

谢谢!

1 个答案:

答案 0 :(得分:2)

简答:
否。

没那么久答案:
你可以用some hacks来实现它,但那会很痛苦。

说明:
根据{{​​3}},getImageData返回一个TypedArray,其中包含画布'图像数据,而不是指向实时imageData的指针作为可修改对象。

要在画布上绘画,您必须使用fillstrokedrawImageputImageData等方法;每次迭代数组时,会更不明白,实际的画布图像会被修改

每次拨打getImageData时,都会创建一个新的TypedArray (请注意选择实际类型the specs,并使用当前数据填充canvasImage的。这样,您可以调用此方法,对ArrayBuffer进行不同的更改,而无需将实际图像修改为画布(因此您可以存储它,或者再次调用该方法)。

至于为什么返回的ImageData的缓冲区在每次调用时都不一样,我认为这是因为"像素必须作为非预乘的alpha值返回",但对于表演,它们确实存储它是预乘的。您可以从Firefox源代码中看到is up to the UA去预复制操作,它实际上填充了一个新的Uint8ClampedArray。 此外,它避免检查自上次调用以来canvasImage是否已被修改,并确保始终获取其当前的ImageData。