繁体   English   中英

HTML、Javascript Canvas 图像并使用 alpha 蒙版图像使其透明

[英]HTML, Javascript Canvas image and make transparent with alpha mask image

我是 html 中的 canvas 的新手,我有两张图片,第一张是普通的 jpeg 图片,第二张是用 alpha(黑白)编辑过的,所以我想让第一张透明,应用来自第二张图片。

图片https://i.stack.imgur.com/fj5mB.jpg

阿尔法面具https://i.stack.imgur.com/5lDgg.png

这是我找到并尝试修改但不起作用的代码。

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

var image = new Image();
image.onload = function() {
    ctx.drawImage(image, 0, 0);
};
image.src = 'image.jpg';

var maskCanvas = document.createElement('canvas');
maskCanvas.width = canvas.width;
maskCanvas.height = canvas.height;
var maskCtx = maskCanvas.getContext('2d');

var mask = new Image();
mask.onload = function() {
    maskCtx.drawImage(mask, 0, 0);
};
mask.src = 'mask.png';

var idata = maskCtx.getImageData(0, 0, maskCanvas.width, maskCanvas.height);
var data32 = new Uint32Array(idata.data.buffer);
var i = 0, len = data32.length;

while(i < len) {
    data32[i] = data32[i++] << 8;
}
ctx.putImageData(idata, 0, 0);

问题的第一部分是图像加载不是同步过程。 这意味着如果 javascript 解释器到达您的代码的这一部分:

ctx.putImageData(idata, 0, 0);

所需的两个图像可能尚未加载,因此两个画布只是空的。 您可以通过将一些console.log()语句插入到onload函数中并紧接在代码的最后一行之前来简单地验证这一点。

 var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var image = new Image(); image.onload = function() { ctx.drawImage(image, 0, 0); console.log("image loaded"); }; image.src = 'https://i.stack.imgur.com/fj5mB.jpg'; var maskCanvas = document.createElement('canvas'); maskCanvas.width = canvas.width; maskCanvas.height = canvas.height; var maskCtx = maskCanvas.getContext('2d'); var mask = new Image(); mask.onload = function() { maskCtx.drawImage(mask, 0, 0); console.log("mask loaded"); }; mask.src = 'https://i.stack.imgur.com/5lDgg.png'; var idata = maskCtx.getImageData(0, 0, maskCanvas.width, maskCanvas.height); var data32 = new Uint32Array(idata.data.buffer); var i = 0, len = data32.length; while (i < len) { data32[i] = data32[i++] << 8; } console.log("drawing"); ctx.putImageData(idata, 0, 0);
 <canvas id="canvas" width="400" height="400"></canvas>

这将记录

drawing
image loaded
mask loaded

到控制台并清楚地显示它正在绘制,然后才可以绘制任何东西。 一种可能的补救措施是使用全局计数器,它会随着每个图像的加载而递增。 一旦它是 2 调用绘图操作。

问题的第二部分是您的代码根本不完整。 这只是两步过程中的第一步 - 将遮罩图像变成实际的 alpha 遮罩,因为它只是一个具有完全不透明 alpha 通道数据的黑白图像。 第二步涉及使用蒙版隐藏部分原始图像。 这可以通过将上下文的globalCompositeOperation更改为destination-in并将掩码绘制到图像的 canvas 上来完成。

这是完整的例子:

 var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var image = new Image(); image.crossOrigin = "Anonymous"; var imagesLoaded = 0; image.onload = function() { imagesLoaded++; ctx.drawImage(image, 0, 0); if (imagesLoaded == 2) { process(); } }; image.src = 'https://api.codetabs.com/v1/proxy?quest=https://i.stack.imgur.com/fj5mB.jpg'; var maskCanvas = document.createElement('canvas'); maskCanvas.width = canvas.width; maskCanvas.height = canvas.height; var maskCtx = maskCanvas.getContext('2d'); var mask = new Image(); mask.crossOrigin = "Anonymous"; mask.onload = function() { imagesLoaded++; maskCtx.drawImage(mask, 0, 0); if (imagesLoaded == 2) { process(); } }; mask.src = 'https://api.codetabs.com/v1/proxy?quest=https://i.stack.imgur.com/5lDgg.png'; function process() { var idata = maskCtx.getImageData(0, 0, maskCanvas.width, maskCanvas.height); var data32 = new Uint32Array(idata.data.buffer); var i = 0, len = data32.length; while (i < len) { data32[i] = data32[i++] << 8; } maskCtx.putImageData(idata, 0, 0); ctx.globalCompositeOperation = "destination-in"; ctx.drawImage(maskCanvas, 0, 0); }
 <canvas id="canvas" width="400" height="400"></canvas>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM