为什么没有图像数据的参考?
Why is there no reference on image data?
是的,我知道 .getImageData()
我的意思是,比方说,我必须更改一些像素:
var imageData = ctx.getImageData(...);
似乎,这种方法给了我 "real"(隐藏在我深处的某处)图像数据的全新副本。
我这么说,因为如果你创建一个新的:
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, ...);
这一个在里面 运行 新循环并复制我的图像数据。
这么多额外的工作!有没有办法在没有 get/put 的情况下获取实际的 imageData 并对其进行操作?如果没有 - 我再问一次 - 为什么?是安全原因吗?他们担心我能用那些像素做什么?
谢谢!
简答:
号
没那么长答案:
您也许可以使用 some hacks 来实现它,但那样会很痛苦。
解释:
根据 the specs,getImageData
returns 包含 canvas' 图像数据的 TypedArray,而不是指向作为可修改对象的实时图像数据的指针。
要在 canvas 上绘画,您必须使用 fill
、stroke
、drawImage
或 putImageData
等方法; 如果每次遍历数组时,实际的 canvas 图像都会被修改 ,那就更没有意义了。
每次调用getImageData
,都会创建一个新的TypedArray
(注意选择实际类型is up to the UA)并填充了 canvasImage 的当前数据。这样,你就可以调用这个方法,在ArrayBuffer上做不同的改动,而不用把实际的图像修改到canvas中(这样你就可以存储它,或者再次调用这个方法)。
至于为什么每次调用返回的ImageData的缓冲区都不一样,我想是因为"Pixels must be returned as non-premultiplied alpha values",但是为了表演,他们确实把它存储为预乘的。可以从Firefox源码中看到here去预乘操作,实际上是填充了一个新的Uint8ClampedArray
此外,它避免检查 canvasImage 自上次调用以来是否已修改,并确保您始终获得其当前 ImageData。
是的,我知道 .getImageData()
我的意思是,比方说,我必须更改一些像素:
var imageData = ctx.getImageData(...);
似乎,这种方法给了我 "real"(隐藏在我深处的某处)图像数据的全新副本。 我这么说,因为如果你创建一个新的:
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, ...);
这一个在里面 运行 新循环并复制我的图像数据。
这么多额外的工作!有没有办法在没有 get/put 的情况下获取实际的 imageData 并对其进行操作?如果没有 - 我再问一次 - 为什么?是安全原因吗?他们担心我能用那些像素做什么?
谢谢!
简答:
号
没那么长答案:
您也许可以使用 some hacks 来实现它,但那样会很痛苦。
解释:
根据 the specs,getImageData
returns 包含 canvas' 图像数据的 TypedArray,而不是指向作为可修改对象的实时图像数据的指针。
要在 canvas 上绘画,您必须使用 fill
、stroke
、drawImage
或 putImageData
等方法; 如果每次遍历数组时,实际的 canvas 图像都会被修改 ,那就更没有意义了。
每次调用getImageData
,都会创建一个新的TypedArray
(注意选择实际类型is up to the UA)并填充了 canvasImage 的当前数据。这样,你就可以调用这个方法,在ArrayBuffer上做不同的改动,而不用把实际的图像修改到canvas中(这样你就可以存储它,或者再次调用这个方法)。
至于为什么每次调用返回的ImageData的缓冲区都不一样,我想是因为"Pixels must be returned as non-premultiplied alpha values",但是为了表演,他们确实把它存储为预乘的。可以从Firefox源码中看到here去预乘操作,实际上是填充了一个新的Uint8ClampedArray
此外,它避免检查 canvasImage 自上次调用以来是否已修改,并确保您始终获得其当前 ImageData。