反转 canvas 图像的 alpha 值

Invert alpha value of a canvas image

反转 canvas 内容的 Alpha 通道的最佳方法是什么?

我见过 this one 这样的解决方案,您可以逐个像素地遍历并重新映射 alpha 值,但这是一项昂贵的操作,我希望可能会有一些东西更高性能(或更好的实践)方法,例如使用 context.filter 或类似方法的方法。

作为一个简化示例,给定此图像,其中所有像素都具有相同的 RGB 通道(黑色)值但不同的 alpha 通道值:

我想生成这张 RGB 通道不变的图像:

请注意,原始图像和最终图像中存在一定范围的 alpha 值。

我们可以使用 globalCompositeOperation 来反转带有 alpha 的颜色。

  1. 具有径向渐变的源图像。

  2. 具有反转 alpha 的结果图像。

  3. 检查结果:在黄色背景上绘制结果图像

const src_canvas = document.querySelector('canvas#source');
const src_ctx = src_canvas.getContext('2d');

const result_canvas = document.querySelector('canvas#result');
const result_ctx = result_canvas.getContext('2d');

const check_canvas = document.querySelector('canvas#check');
const check_ctx = check_canvas.getContext('2d');

const w = src_canvas.width = result_canvas.width = check_canvas.width = 180;
const h = src_canvas.height = result_canvas.height = check_canvas.height = 180;

const gradient = src_ctx.createRadialGradient(w/2,h/2,0, w/2,h/2,w/3);
gradient.addColorStop(0, 'rgba(0,0,0,1)');
gradient.addColorStop(1, 'rgba(0,0,0,0)');

src_ctx.fillStyle = gradient;
src_ctx.fillRect(0,0,w,h);

result_ctx.drawImage(src_canvas,0,0);
result_ctx.globalCompositeOperation = 'source-out';
result_ctx.fillRect(0,0,w,h); // uses default fillStyle = 'black'

check_ctx.fillStyle = 'yellow'; // to check if the figure isn't fully opaque
check_ctx.fillRect(0,0,w,h);

check_ctx.drawImage(result_canvas,0,0);
<canvas id="source"></canvas>
<canvas id="result"></canvas>
<canvas id="check"></canvas>

仅当渐变的基色(你的透明图像)和fillStyle的颜色在应用globalCompositeOperation="source-out" 是一样的。如果您的透明图像中有不同的颜色 - 它不会起作用。

我将黑色作为透明图像的基色 rgba(0,0,0,...),并在 result_ctx.fillRect(0,0,w,h) 时将黑色作为默认填充颜色。例如,如果源图像的基色是红色 ('rgba(255,0,0,...)'),那么我们必须在 fillRect() -> result_ctx.fillStyle = 'red' ('rgb(255,0,0)');

之前明确定义它