使用getImageData - HTML5 2d Context丢失透明度

时间:2013-01-01 13:11:42

标签: javascript html5 canvas getimagedata

我发现了getImageData的一个奇怪问题;在获取图像数据时,图像的透明度似乎被忽略。

由于在获取图像数据之前需要将任何图像绘制到canvas,我认为这是一个问题,canvas有问题是不透明的。但我错了,因为在canvas中使用drawImage作为参数可以保持透明度。

以下是我加载图片的方式;

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只是绘制函数,它调用draw_image来绘制图像。

通常的版本;

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

它只是将画布作为drawImage的参数,结果与预期的透明度保持一致。的 Example

图像数据版本;

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);
};

这个从与普通版本中使用的画布相同的画布获取所需矩形的图像数据,并将图像数据放在我想要绘制的画布上。我认为应保持透明度,但事实并非如此。的 Example 即可。 (由于origin-clean标志,这是一个Dropbox链接。)

我认为应该用getImageData保持透明度是错误的吗?或者我只是以错误的方式使用它?

不管怎样,帮助真的很值得赞赏。

1 个答案:

答案 0 :(得分:7)

我相信你的问题是putImageData不使用composite operation来混合源图像数据和目标图像数据。相反,它正在将红色,绿色,蓝色,和alpha 通道直接写入画布。对于完全透明的像素,这意味着它们可能会或可能不会以您期望的颜色显示。

相反,您可以创建一个中间画布元素,绘制到该元素,然后使用drawImage()将其渲染到目标画布,并应用相应的globalCompositeOperation。 Mask for putImageData with HTML5 canvas?更详细地讨论了这个问题。

更新:您可以通过执行ctx.getImageData(230,50,1,1).data来验证您写入“已损坏”示例的数据是否确实在其中包含透明数据。结果是[0,0,0,0] - 即完全透明的像素。