Transparency lost with getImageData - HTML5 2d Context

I noticed a strange problem with getImageData ; image transparency is apparently ignored when receiving image data.

Since any image must be drawn on canvas before its data can be retrieved, I assumed that this is a problem with an opaque canvas . But I was wrong, since using canvas as an argument in drawImage supports transparency.

This is how I uploaded the image;

 var load_image = function(name, url, holder, callback) { var img = new Image(); img.src = url; img.addEventListener('load', function(e) { var canvas = make_canvas(e.target.width, e.target.height); var ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(e.target, 0, 0); holder[name] = {canvas: canvas, ctx: ctx}; delete e.target; callback.call(); }, false); }; 

callback is just a drawing function that calls draw_image to draw an image.

Normal version;

 var draw_image = function(ctx, img, sx, sy, w, h, dx, dy) { ctx.drawImage(img.canvas, sx, sy, w, h, dx, dy, w, h); }; 

It just takes the canvas as an argument for drawImage , and the result will be the same as when maintaining transparency. An example .

Version of image data;

 var draw_image = function(ctx, img, sx, sy, w, h, dx, dy) { var imagedata = img.ctx.getImageData(sx, sy, w, h); ctx.putImageData(imagedata, dx, dy); }; 

This one gets the image data of the required rectangle from the same canvas as in the regular version, and puts the image data on the canvas that I want to draw. I believe that transparency should be supported, but it is not. An example . (This is a Dropbox link due to the origin-clean flag.)

Am I mistaken in believing that transparency should be supported with getImageData ? Or am I using it incorrectly?

In any case, the help would be really appreciated.

+6
source share
1 answer

I believe your problem is that putImageData does not use a composite operation to mix the source and target image data. Rather, he makes a direct recording of red, green, blue and alpha channels into the canvas. For fully transparent pixels, this means that they may or may not appear in the expected color.

Instead, you can create an intermediate canvas element, draw on it, and then use drawImage () to display this on your target canvas using the appropriate globalCompositeOperation. The mask for putImageData with an HTML5 canvas discusses this issue in more detail.

Update. You can verify that the data you write in your โ€œbrokenโ€ example actually has transparent data by making ctx.getImageData(230,50,1,1).data . The result is [0,0,0,0] - that is, a fully transparent pixel.

+7
source

All Articles