[英]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.