6

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

canvas由于在获得图像数据之前需要将任何图像绘制到 a 上,我认为这是一个问题,因为canvas问题是不透明的。但我错了,因为使用 thecanvas作为参数来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,结果与预期的一样,并保持了透明度。例子

图像数据版本;

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

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

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

无论哪种方式,我们都会非常感谢您的帮助。

4

1 回答 1

8

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

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

更新:您可以通过执行ctx.getImageData(230,50,1,1).data. 结果是 [0,0,0,0] - 即完全透明的像素。

于 2013-01-01T13:43:09.713 回答