使用getImageData时,透明度丢失 - HTML5 2d上下文

6
我注意到一个关于getImageData的奇怪问题:当获取图像数据时,图像的透明度似乎被忽略了。
由于任何图像在获取其图像数据之前都需要绘制到canvas上,所以我认为这是涉及的canvas不透明的问题。但是我错了,因为在drawImage中使用canvas参数会保持透明度。
下面是我加载图像的方法;
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);
};
回调函数就是简单的绘图函数,它调用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的参数,并且结果如预期一样保持透明度。 示例

图像数据版本;

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

这段代码从同一画布中获取所需矩形的图像数据,并将该图像数据放在我想要绘制的画布上。我认为透明度应该得到保留,但事实并非如此。这是个例子(因为存在origin-clean标志,所以这是Dropbox链接):Example
使用getImageData时,我的假设是保持透明度,但是我是否使用方法不当?无论如何,真的需要帮助。
1个回答

8
我相信你的问题在于putImageData函数没有使用合成操作来混合源图像和目标图像数据。相反,它将红色、绿色、蓝色和透明度通道直接写入画布中。对于完全透明的像素,这意味着它们可能会以你不期望的颜色出现或者不出现。
相反地,你可以创建一个中间画布元素,绘制到其中,然后使用drawImage()将其呈现到你的目标画布上,并应用适当的全局合成操作。HTML5画布putImageData的遮罩?详细讨论了这个问题。
更新:通过执行ctx.getImageData(230,50,1,1).data,你可以验证你在"broken"示例中写入的数据实际上确实具有透明数据。结果为[0,0,0,0],即完全透明的像素。

1
我明白了,这解释了很多!感谢你的回答!不过,这真的让事情变得复杂了。我原本计划测试使用canvas作为游戏中的“图像”(颜色掩蔽和透视变换)是否比开销更大。如果我需要引入一个中间画布来绘制转换后的图像,那么我还不如使用Image对象和粗略的canvas进行处理。再次感谢! - Rikonator

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接