javascriptcanvashtml5-canvasgetimagedata

Is there a way to reuse an ImageData to reduce GC activity?


I'm looking for a GC-friendly way to use CanvasRenderingContext#getImageData. One idea is to create an ImageData once and somehow reuse it so that the getImageData would not allocate a new one. Since I need to access the raw canvas data around 60 times per second, I cannot really afford to allocate a new ImageData everytime I use getImageData. Is this possible?


Solution

  • Not if you need to draw using anything else than the buffer's data manipulation + putImageData.

    The ImageData object returned by ctx.getImageData() is a copy of the underlying canvas' buffer, it is not linked to that internal buffer by any means, and there is no way that any update to the canvas would make any change to the returned ImageData.

    Note that there are active discussions about doing zero copy from the canvas API to for instance WebAssembly. One idea would be to extend getImageData() so it "takes a view into which bytes can be written". But this is just at the discussion stage, and we'll probably have to wait some time to see any viable solution to this more and more common issue.

    If you were to draw only by ctx.putImageData() after you change the data in the ImageData though, then you could of course just keep the same ImageData and never request any new, since your ImageData would always be up to date.

    Also, one quite frequent misuse of ImageData is when we want to send it to WebWorkers for processing, don't forget to transfer it by using the second parameter of worker.postMessage() otherwise you'd duplicate this data at each message.