Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting Uint8ClampedArray to ImageData is very slow in Firefox

I am running the following code:

ImageData imagedata = context.getImageData(0, 0, width, height);
Uint8ClampedArray pixelArray;
...

imagedata.data.set(pixelArray);

This code run fast in Chrome but very slow in Firefox. Is there a faster way to write Uint8ClampedArray to an ImageData?

like image 418
Erik Sapir Avatar asked Nov 14 '12 18:11

Erik Sapir


1 Answers

The fastest way to write a Uint8ClampedArray to an imageData is to write a Uint8ClampedArray that was not first obtained by getImageData. context.getImageData is ridiculously slow. I have made a test on jsPerf which demonstrates where the time is going in the code you have posted. The first test writes an existing array to an imageData, while the second test reads from an existing imageData. The second test takes up over 99% of the time.

So, what can you do about it?

Instead of creating your Uint8ClampedArray from context.getImageData, try creating it via new Uint8ClampedArray(width*height*channels). Alternatively, if you wish to write to the imageData many times, but you can get away with only reading from it once, cache the Uint8ClampedArray and don't recreate it from whatever imageData returns.

I ran across this problem myself, a few weeks ago. I actually ended up redoing a bit of program to avoid ever reading from the context. Even though getImageData is much faster in Chrome, it still had a small impact on the framerate of the browser when I tried running it every frame. I've got the project up on dropbox, and the JS is unobfuscated so you can just inspect it if you want to see what someone else has done with the problem.

Hope that helps!

like image 199
DDR Avatar answered Oct 03 '22 07:10

DDR