简体   繁体   English

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

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

I am new with canvas in html, I have two images first one is a normal jpeg image and the second is the same edited with alpha (black and white) so the thing is I want to make the first transparent applying the alpha mask from the second image.我是 html 中的 canvas 的新手,我有两张图片,第一张是普通的 jpeg 图片,第二张是用 alpha(黑白)编辑过的,所以我想让第一张透明,应用来自第二张图片。

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

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

Here the code that I found and tried to modify but doesn't work.这是我找到并尝试修改但不起作用的代码。

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

The first part of your problem is that image loading is not a synchronous process.问题的第一部分是图像加载不是同步过程。 That means if the javascript interpreter reaches this part of your code:这意味着如果 javascript 解释器到达您的代码的这一部分:

ctx.putImageData(idata, 0, 0);

the two images required might not have loaded yet thus the two canvases are just empty.所需的两个图像可能尚未加载,因此两个画布只是空的。 You can simply verify this by inserting some console.log() statements into the onload functions and just before the last line of your code.您可以通过将一些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>

This will log这将记录

drawing
image loaded
mask loaded

to the console and clearly reveal that it's drawing before there is anything to draw.到控制台并清楚地显示它正在绘制,然后才可以绘制任何东西。 One possible remedy is using a global counter which increments with each image loaded.一种可能的补救措施是使用全局计数器,它会随着每个图像的加载而递增。 As soon as it's 2 call the drawing operation.一旦它是 2 调用绘图操作。

The second part of your problem is that your code simply is not complete.问题的第二部分是您的代码根本不完整。 It's just the first step in a two step process - turning the mask image into an actual alpha mask as it's just a black & white image with fully opaque alpha channel data.这只是两步过程中的第一步 - 将遮罩图像变成实际的 alpha 遮罩,因为它只是一个具有完全不透明 alpha 通道数据的黑白图像。 The second step involves using the mask to hide parts of the original image.第二步涉及使用蒙版隐藏部分原始图像。 This can be done by changing the globalCompositeOperation of the context to destination-in and just drawing the mask onto the image's canvas.这可以通过将上下文的globalCompositeOperation更改为destination-in并将掩码绘制到图像的 canvas 上来完成。

Here's the complete example:这是完整的例子:

 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