HTML、Javascript Canvas 图像并使用 alpha 蒙版图像使其透明
HTML, Javascript Canvas image and make transparent with alpha mask image
我是 html 中 canvas 的新手,我有两张图片,第一张是普通的 jpeg 图片,第二张是用 alpha(黑白)编辑过的,所以问题是我想应用第二张图片的 alpha 蒙版使第一张透明。
图片https://i.stack.imgur.com/fj5mB.jpg
Alpha 蒙版 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);
所需的两个图像可能尚未加载,因此两个 canvases 只是空的。
您可以通过在 onload
函数中并在代码的最后一行之前插入一些 console.log()
语句来简单地验证这一点。
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>
我是 html 中 canvas 的新手,我有两张图片,第一张是普通的 jpeg 图片,第二张是用 alpha(黑白)编辑过的,所以问题是我想应用第二张图片的 alpha 蒙版使第一张透明。
图片https://i.stack.imgur.com/fj5mB.jpg
Alpha 蒙版 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);
所需的两个图像可能尚未加载,因此两个 canvases 只是空的。
您可以通过在 onload
函数中并在代码的最后一行之前插入一些 console.log()
语句来简单地验证这一点。
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>