在html canvas中如何将黑白蒙版转换为黑色透明蒙版?

问题描述 投票:0回答:1

画布中是否可以将黑/白蒙版转换为黑/透明蒙版? 我到处搜索,唯一的方法是使用像素操作,太慢了

基本上我想要这个转变:

var ac = a.getContext('2d');
var g = ac.createLinearGradient(25, 0, 75, 0);
g.addColorStop(0, 'black');
g.addColorStop(1, 'white');
ac.fillStyle = 'white';
ac.fillRect(0, 0, 100, 100);
ac.fillStyle = g;
ac.fillRect(25, 25, 50, 50);

var bc = b.getContext('2d');
var g = bc.createLinearGradient(25, 0, 75, 0);
g.addColorStop(0, 'black');
g.addColorStop(1, '#00000000');
bc.fillStyle = g;
bc.fillRect(25, 25, 50, 50);
body {
  background-color: pink;
}

canvas {
  outline: 1px solid cyan;
}
Convert this:<canvas id="a" width="100" height="100"></canvas>
to this:<canvas id="b" width="100" height="100"></canvas>

我得到的最接近的是使用乘法:

var a = document.getElementById('a'),
    m = document.getElementById('m'),
    c = document.getElementById('c');

// green image
a.context = a.getContext('2d');
a.context.fillStyle = 'green';
a.context.fillRect(0, 0, 100, 100);

// black and white mask
m.context = m.getContext('2d');
m.context.fillStyle = 'white';
m.context.fillRect(0, 0, 100, 100);

var g = m.context.createLinearGradient(25, 0, 75, 0);
g.addColorStop(0, 'black');
g.addColorStop(1, 'white');

m.context.fillStyle = g;
m.context.fillRect(25, 25, 50, 50);

// result
c.context = c.getContext('2d');
c.context.drawImage(a, 0, 0);
c.context.globalCompositeOperation = "multiply";
c.context.drawImage(m, 0, 0);
body {
  background-color: cyan;
}
Green image:
<canvas id="a" width=100 height=100 style="outline: 1px solid cyan;"></canvas>
Black and white mask:
<canvas id="m" width=100 height=100 style="outline: 1px solid cyan;"></canvas>
Result:
<canvas id="c" width=100 height=100 style="outline: 1px solid cyan;"></canvas>

但问题在于,没有中间步骤可以让我访问黑色/透明画布。

javascript html canvas
1个回答
0
投票

最好的方法是按照您需要使用的方式准备您的资产。
因此,如果可能的话,根本不要生成或存储不透明渐变。


现在,我毫不怀疑这可能无法在所有情况下实现......
SVG

luminanceToAlpha
 上有 
<feColorMatrix>
效果,您也可以在 2D 画布中使用该效果。它将所有低亮度的像素转换为透明像素,将高亮度的像素转换为不透明的黑色,这与您想要的相反,因为在渐变上,白色像素将变为黑色,黑色像素将变为透明。 所以我们需要先反转渐变,然后应用
luminanceToAlpha
:

var a = document.getElementById('a'),
    m = document.getElementById('m'),
    c = document.getElementById('c');

// green image
a.context = a.getContext('2d');
a.context.fillStyle = 'green';
a.context.fillRect(0, 0, 100, 100);

// black and white mask
m.context = m.getContext('2d');
m.context.fillStyle = 'white';
m.context.fillRect(0, 0, 100, 100);

var g = m.context.createLinearGradient(25, 0, 75, 0);
g.addColorStop(0, 'black');
g.addColorStop(1, 'white');

m.context.fillStyle = g;
m.context.fillRect(25, 25, 50, 50);

// result
c.context = c.getContext('2d');
c.context.drawImage(a, 0, 0);
c.context.filter = "invert(1) url(#lumToAlpha)";
c.context.drawImage(m, 0, 0);
body {
  background-color: cyan;
}
Green image:
<canvas id="a" width=100 height=100 style="outline: 1px solid cyan;"></canvas>
Black and white mask:
<canvas id="m" width=100 height=100 style="outline: 1px solid cyan;"></canvas>
Result:
<canvas id="c" width=100 height=100 style="outline: 1px solid cyan;"></canvas>
<svg width="0" height="0" style="position:absolute">
  <filter id="lumToAlpha"><feColorMatrix type="luminanceToAlpha"/></filter>
</svg>

这种方法有一个很大的缺点:Safari 还不支持 2D 画布的

filter
。他们终于正在研究它,在切换一些标志后甚至可以在最新的技术预览中进行测试,但它还不稳定,因此对于大多数 iPhone 用户来说,您需要回退到
ImageData
操作。
要测试支持,您可以检查 2D 上下文的
filter
在您未设置时是否返回
"none"

const supportsCanvasFilters = new OffscreenCanvas(1,1).getContext("2d").filter==="none";
© www.soinside.com 2019 - 2024. All rights reserved.