I am drawing a byte array of image data to a canvas with putImageData. The image data has some transparency, but when I draw multiple images to the canvas I don't see any overlap. In other words, I get this:

But I want this:

I am clearly not understanding something about how alpha compositing works in Javascript/HTML, and I hope someone can help me with this problem. Thanks!
Sample code:
const arr = new Uint8ClampedArray(4*100*100);
for (let i = 0; i < arr.length; i += 4) {
arr[i + 0] = 255;
arr[i + 1] = 0;
arr[i + 2] = 0;
arr[i + 3] = 100;
}
let imageData = new ImageData(arr, 100);
context.putImageData(imageData, 0, 0);
context.putImageData(imageData, 50, 50);
The thing is that putImageData (and to some extents getImageData too), is special: it won't care at all about the current context settings, that is, it will completely ignore the current context's transformation matrix, all its clipping regions, it will ignore the current context's filter, its shadowColor, its globalAlpha, etc. and back to our case, its globalCompositeOperation.
What it does is it sets the pixels on the canvas buffer at the untransformed coordinates to what is stored in the ImageData object.
So, yes, it will not composite your ImageData content with what was there, it will just replace it.
If you wish to draw your ImageData content as if it were a mere bitmap content, you can convert it to an ImageBitmap instead:
(async() => {
const canvas = document.querySelector("canvas");
const context = canvas.getContext("2d");
const arr = new Uint8ClampedArray(4*100*100);
for (let i = 0; i < arr.length; i += 4) {
arr[i + 0] = 255;
arr[i + 1] = 0;
arr[i + 2] = 0;
arr[i + 3] = 100;
}
let imageData = new ImageData(arr, 100);
const bmp = await createImageBitmap(imageData);
context.drawImage(bmp, 0, 0);
context.drawImage(bmp, 50, 50);
})();
<canvas></canvas>
Though beware this method is somehow async, so in an animation frame that might not be the best to use, and you may prefer falling back on using a second, offscreen, canvas, at the cost of a bigger memory impact.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With