Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to draw an Uint8ClampedArray directly to a canvas?

In JavaScript, you can manipulate pixels of an image directly using an Uint8ClampedArray. Before rendering that image to a canvas, you have to:

  1. Create an ImageData object.

  2. Render the Uint8ClampedArray to an ImageData object with ImageData.data.set.

  3. Draw that ImageData object to the canvas with context.putImageData.

So, from having an Uint8ClampedArray with your image, to actually seeing it on screen, it takes no less than 3 O(N) copying operations. For big images, that can be very detrimental. One solution would be to cache the ImageData object, and replace the pointer imageData.data to your Uint8ClampedArray - but imageData.data is readonly! Is there any way to do this more efficiently?

like image 242
MaiaVictor Avatar asked Aug 01 '15 02:08

MaiaVictor


People also ask

How do you get pixels on canvas?

To get the pixel of any specific portion from HTML canvas you can use the HTML canvas getImageData() Method. The getImageData() method usually returns an ImageData object that contains the pixel information of the specified object on the HTML canvas.

How do I get image data from canvas?

To get the image data for each pixel of a rectangular area on the canvas, we can get the image data object with the getImageData() method of the canvas context and then access the pixel data from the data property. Each pixel in the image data contains four components, a red, green, blue, and alpha component.

What is Uint8ClampedArray?

The Uint8ClampedArray typed array represents an array of 8-bit unsigned integers clamped to 0-255; if you specified a value that is out of the range of [0,255], 0 or 255 will be set instead; if you specify a non-integer, the nearest integer will be set. The contents are initialized to 0 .


1 Answers

According to MDN's page on ImageData, the ImageData(array, width, height) constructor takes a first argument that is

A Uint8ClampedArray containing the underlying pixel representation of the image.

A quick test verifies that this argument is used by reference (i.e., not copied) as the ImageData's data property. This test logs true:

var arr = new Uint8ClampedArray([0,0,0,0]);
var idata = new ImageData(arr,1,1);
console.log(idata.data === arr);

Thus, you can eliminate your second step by constructing the ImageData object in your first step with data property that references your Uint8ClampedArray object.

like image 89
apsillers Avatar answered Sep 30 '22 14:09

apsillers