javascript - 使用 getImageData 时透明度丢失 - HTML5 2d 上下文
我注意到 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);
};
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 时保持透明度?还是我只是使用方式不正确?
无论哪种方式,帮助都会非常感激。
答案#1
我认为你的问题在于 putImageData 并没有使用复合操作来混合源图像数据和目标图像数据。相反,它是直接将红色、绿色、蓝色和 alpha 通道写入画布。对于完全透明的像素,这意味着它们可能会显示也可能不会显示为你期望的颜色。
相反,你可以创建一个中间的 canvas 元素,先在其上绘制,然后使用 drawImage() 将其渲染到目标 canvas,同时应用适当的 globalCompositeOperation。 关于 HTML5 canvas 中 putImageData 的遮罩?详细讨论了这个问题。
更新:你可以通过执行 ctx.getImageData(230,50,1,1).data 来验证你写入“损坏”示例的数据实际上确实包含透明数据。结果是 [0,0,0,0] —— 即一个完全透明的像素。