答案 0 :(得分:16)
可以使用context.globalCompositeOperation制作掩码
context.drawImage(img, 0, 0, img.width, img.height, 0,0, img.width, img.height);
context.globalCompositeOperation = "destination-out";
gradient = context.createLinearGradient(0, 0, 0, img.height);
gradient.addColorStop(0, "rgba(255, 255, 255, 0.5)");
gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)");
context.fillStyle = gradient;
context.fillRect(0, 0, img.width, img.height);
这不是每像素操作而应该更快
答案 1 :(得分:10)
要使用透明蒙版正确合并两个图像,首先需要拍摄两个图像中的一个并将其放入 off screen 画布,然后使用context.globalCompositeOperation = destination-out
添加所需的透明蒙版per @ Tommyka的回答
var offscreen = document.createElement('canvas'); // detached from DOM
var context = offscreen.getContext('2d');
context.drawImage(image1, 0, 0, image1.width, image1.height);
var gradient = context.createLinearGradient(0, 0, 0, img.height);
gradient.addColorStop(0, "rgba(255, 255, 255, 0.5)");
gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)");
context.globalCompositeOperation = "destination-out";
context.fillStyle = gradient;
context.fillRect(0, 0, image1.width, image1.height);
然后,要实际合并这两个图像,您需要将另一个图像绘制到另一个画布中,然后简单地在其上绘制alpha合成的屏幕外画布:
var onscreen = document.getElementById('mycanvas');
var context2 = onscreen.getContext('2d');
context2.drawImage(image2, 0, 0, image2.width, image2.height);
context2.drawImage(offscreen, 0, 0, onscreen.width, onscreen.height);
演示
答案 2 :(得分:7)
答案 3 :(得分:0)
答案 4 :(得分:0)
我通过合并图像的异步加载来实现Alnitak's response的现代化。
我也摆脱了魔术数字。
const imageUrls = [
// Base image
'http://www.netstate.com/states/symb/flowers/images/apple_blossoms.jpg',
// Gradient image
'http://www.netstate.com/states/symb/flowers/images/oklahoma_rose.jpg'
];
const main = async () => {
const ctx = document.getElementById('cv').getContext('2d'),
baseImg = await loadImage(imageUrls[0]),
gradImg = await loadImage(imageUrls[1]);
draw(ctx, baseImg, gradImg);
};
/**
* Loads an Image object via a Promise.
* @param {String} url - Location of an image file
* @return {Promise<Image>} Returns a promise that resolves to an Image.
*/
const loadImage = (url) => new Promise((resolve, reject) => {
const img = new Image();
img.addEventListener('load', () => resolve(img));
img.addEventListener('error', reject);
img.src = url;
});
/**
* Draws an image, as a gradient applied to it, above another image.
* @param {Image} baseImg - Image that is applied under the gradient
* @param {Image} gradImg - Image to be applied as a gradient
*/
const draw = (ctx, baseImg, gradImg) => {
const {width, height} = baseImg,
originX = Math.floor(width / 2),
originY = Math.floor(height / 2),
radius = Math.min(originX, originY);
const offScreen = document.createElement('canvas');
offScreen.width = offScreen.height = width;
const ctx2 = offScreen.getContext('2d');
ctx2.drawImage(gradImg, 0, 0, width, height);
const gradient = ctx2.createRadialGradient(originX, originY, 0, originX, originY, radius);
gradient.addColorStop(0, 'rgba(255, 255, 255, 0)');
gradient.addColorStop(1, 'rgba(255, 255, 255, 1)');
ctx2.fillStyle = gradient;
ctx2.globalCompositeOperation = 'destination-out';
ctx2.fillRect(0, 0, width, height);
ctx.drawImage(baseImg, 0, 0, width, height);
ctx.drawImage(offScreen, 0, 0, width, height);
};
main();
<canvas id="cv" width="300" height="300"></canvas>