Philipp
Philipp

Reputation: 2526

Draw an exisiting ArrayBuffer into a Canvas without copying

I have an Uint8ClampedArray which contains a bitmap. The following works but I want to avoid the copying of the buffer and as I understand ImageData.set copies the ArrayBuffer.

var mappedBuffer = new Uint8ClampedArray(Module.HEAPU8.buffer, offset, length); // Creates a view on the emscripten heap
var imageData = ctx.createImageData(width, height);
imageData.data.set(mappedBuffer); // copy here
ctx.putImage(imageData, 0, 0);

Is there a way to avoid copying so that the we can directly draw to the canvas without a copy first?

Upvotes: 10

Views: 13098

Answers (1)

user1693593
user1693593

Reputation:

There is the creating of ImageData manually that now can be used in some browser (intended for workers, but can be used from main thread as well). It takes an existing array with a Uint8ClampedArray view on top as argument together with width and height.

Since it takes a view, the underlying ArrayBuffer is simply referenced instead of copied (just have in mind that putImageData() will always need to copy the data).

var iData = new ImageData(clampedArray, width, height);

This can then be used with putImageData().

// create custom array view and fill with some random data
var array = new Uint32Array(100*100);
for(var i=0; i < array.length; i++) array[i] = 0xff000000|(Math.sin(i*0.0001)*0xffffff);

// create ImageData instance
var iData = new ImageData(new Uint8ClampedArray(array.buffer), 100, 100);
var ctx = c.getContext("2d");
ctx.putImageData(iData, 0, 0);
<canvas id=c width=100 height=100></canvas>

Upvotes: 17

Related Questions