1

From the code below you can see that I misunderstand how putImageData works:

// create canvas:
let canvas = document.createElement("canvas");
canvas.width = 2;
canvas.height = 1;
let ctx = canvas.getContext("2d");

// grab its imageData:
let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
console.log(imageData.data);

// edit its imageData:
imageData.data[0] = 10;
console.log(imageData.data);

// put the edited image data onto the canvas:
ctx.putImageData(imageData, 0, 0);

// check that the edited data is actually on the canvas:
let finalImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
console.log(finalImageData.data);

That code outputs these logs:

[0, 0, 0, 0, 0, 0, 0, 0]
[10, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]

I expected that last console.log to output [10, 0, 0, 0, 0, 0, 0, 0]. Where am I going wrong in my understanding here?

(To be sure, I've tested with Firefox and Chrome - same result. Definitely seems like a very fundamental misunderstanding on my part.)

joe
  • 3,752
  • 1
  • 32
  • 41

1 Answers1

2

You need to set the alpha to 255 or the canvas is just drawing something transparent, the data is a sequence of RGBA items

Your data output of [0, 0, 0, 0, 0, 0, 0, 0] can be represented as

R G B A
0 0 0 0
0 0 0 0

Some good reading:

Here is your code but setting the alpha on the first pixel to 255

// create canvas:
let canvas = document.createElement("canvas");
canvas.width = 2;
canvas.height = 1;
let ctx = canvas.getContext("2d");

// grab its imageData:
let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
console.log(imageData.data);

// edit its imageData:
imageData.data[0] = 10;
imageData.data[3] = 255;
console.log(imageData.data);

// put the edited image data onto the canvas:
ctx.putImageData(imageData, 0, 0);

// check that the edited data is actually on the canvas:
let finalImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
console.log(finalImageData.data);
Helder Sepulveda
  • 15,500
  • 4
  • 29
  • 56
  • 2
    To be correct, the issue here is that the pixels are stored with their alpha premultiplied in the canvas buffer. So whatever-RGB x alpha-0 will be stored as 0. This formats allows for faster processing later. OP could have set the alpha to something else than 0 or 255 to get something in their R channel (though not necessarily the value they did set) – Kaiido Apr 10 '21 at 00:17
  • 1
    @Kaiido do you have some references to the `alpha premultiplied` I was running some test and getting some "interesting" results there is some calculation been done but does not look like a multiplication – Helder Sepulveda Apr 10 '21 at 01:03
  • 1
    https://html.spec.whatwg.org/multipage/canvas.html#premultiplied-alpha-and-the-2d-rendering-context https://stackoverflow.com/questions/23497925/how-can-i-stop-the-alpha-premultiplication-with-canvas-imagedata https://github.com/whatwg/html/pull/5371 – Kaiido Apr 10 '21 at 01:12