Pregunta

I'm using a HTML canvas to project an image. When i try to manipulate the image data's Alpha channel I'm seeing that anytime it is zeroed, the other values in the pixel get changed. Even when set to a low number they seem to change. Doing this from the console

canvas=document.getElementById('canvasid')
ctx=canvas.getContext('2d')
mydata=ctx.getImageData(20,20,20,20)
for (var i=0;i<1600;i+=4){mydata.data[i+3]=0}
ctx.putImageData(mydata,20,20)
mydata=ctx.getImageData(20,20,20,20)
for (var i=0;i<1600;i+=4){mydata.data[i+3]=255}
ctx.putImageData(mydata,20,20)

results in a black square instead of a restoring the image that should be in the RGB values.

happens in both Chrome and Safari, haven't tested others

any clues as to what i'm doing wrong.

¿Fue útil?

Solución

There is several issues in webkit browsers (and probably Blink as well) when it comes to the alpha channel and canvas. Here is a related issue.

What markE answers may be what actually happens but it's not what should happen. The whole point with the alpha channel is that the RGB values are left untouched (as well as avoid manual color mixing etc.).

Webkit browser would need to pre-multiply the value (when composited in the browser) but the result of this seem to "leak" into the canvas' bitmap which it shouldn't.

You are correctly expecting the values to stay untouched when changing the alpha channel. This is a bug and you should report it to the Chromium team (edit: now has been reported).

Possible work-around

The only work-around I can think of on the fly, would be to keep the original image data as a separate buffer and copy data from that source buffer to the destination buffer while altering the alpha channel.

Of course, if you need to update the RGB/pixels data in the mean time you would be back to the same situation before unless you are willing to update pixels (RGB) only for the off-screen buffer - this can be done using a 32-bits typed array buffer masking the alpha channel (performance reduction will occur).

Otros consejos

When you write a fully transparent pixel to the canvas (alpha==0), the browser automatically fills the r,g,b values with zero.

So your first putImage fills with rgba(0,0,0,0);

When you again getImage those pixels and you change the transparency to 255 (fully opaque) you have rgba(0,0,0,255);

This is the rgb for black.

That's why your code results in black pixels.

If you want to restore the original pixels, you can do putImageData with your original mydata (without refetching with another getImageData).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top