I want to take an ArrayBuffer or Uint8Array element and convert them to ImageData element, and eventually to Canvas element.
Is it possible?
It would go something like this in pure javascript:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var imgData = ctx.createImageData(100,100);
var buffer = new ArrayBuffer(4*100*100);
var ubuf = new Uint8Array(buffer);
for (var i=0;i < ubuf.length; i+=4) {
imgData.data[i] = ubuf[i]; //red
imgData.data[i+1] = ubuf[i+1]; //green
imgData.data[i+2] = ubuf[i+2]; //blue
imgData.data[i+3] = ubuf[i+3]; //alpha
}
ctx.putImageData(imgData,0,0);
To do this in GWT you need to wrap this in a JSNI method
new ImageData( new Uint8ClampedArray(buffer), width, height); will work (no need to copy the values in a for() loop). developer.mozilla.org/en-US/docs/Web/API/ImageData/ImageData2021 answer
The ImageData constructor now supports an optional Uint8ClampedArray parameter in most browsers, so no need to copy the values in a for() loop as rzymek suggested back in 2013.
So based on his example:
const buffer = ArrayBuffer(4 * 100 * 100)
const ui8ca = new Uint8ClampedArray(buffer);
const imageData = new ImageData(ui8ca, 100, 100);
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
ctx.putImageData(imageData, 0, 0);
Works in all modern browsers except Internet Explorer and Android Webview.
See https://developer.mozilla.org/en-US/docs/Web/API/ImageData/ImageData
ctx.createImageData() instead of new ImageData() - the former does NOT support Uint8ClampedArray as a param, the latter does.const imageData = new ImageData(ui8ca, 100, 100);