簡體   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