【问题标题】:SVG filter to map alpha values to RGB values in a table?SVG过滤器将alpha值映射到表格中的RGB值?
【发布时间】:2018-12-16 11:52:07
【问题描述】:

我知道如何使用feComponentTransfer 来调整RGBA 值,使用tabletableValues

但是有没有办法使用 alpha 值作为输入(例如)来调整 R、G 或 B 值?

为什么?假设我合成了许多半透明的形状,在这些形状重叠的地方产生了不同的不透明度。我想使用这些不透明度值来使用基于每个像素不透明度的查找表来调整 RGB。

例如,在this image 中,椭圆、正方形和文本使用 alpha 0.1 绘制。重叠区域具有更高的 alpha 值。

如何将这张图像中的每个像素用 alpha 0.1 映射到 rgba(255,0,0,1) 以及在任何地方用 alpha 0.2 映射到 rgba(0,255,0,1)(并在抗锯齿边缘上的这两个 alpha 值之间插入替换颜色)?更多颜色将分配给所有其他不超过 1 的 alpha 值。

制作这样一个查找表很容易。

但是如何使用 svg 过滤器应用于图像?

【问题讨论】:

  • 我认为没有一种简单的方法可以捕捉 alpha 层并为每个 alpha 值分配不同的颜色。

标签: svg svg-filters


【解决方案1】:

您可以实现它,但这是一个多步骤的过程,您必须自己了解性能和可维护性。

我的示例代码将不透明度值划分为四个等距的范围:0.2...0.4...0.6...0.8...1。范围 0...0.2 映射到透明度。

对于四个颜色范围中的每一个,您需要组合三个过滤器原语:

  • 选择SourceAlpha作为输入,并将<feComponentTransfer>应用于discrete类型的alpha通道,这样只有一个范围映射到opacity="1"
  • 用指定颜色的<feFlood> 填充过滤区域
  • 将第一个和第二个结果与<feComposite>operator="in" 组合在一起,这样只有映射的值会被着色

然后,将所有不同的单色部分与<feMerge>合并在一起。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="200">
  <linearGradient id="sourceGradient" x1="0" x2="1" y1="0" y2="0">
    <stop style="stop-color:#000000;stop-opacity:0" offset="0" />
    <stop style="stop-color:#000000;stop-opacity:1" offset="1" />
  </linearGradient>
  <filter id="filter">
    <feComponentTransfer in="SourceAlpha" result="step1">
      <feFuncA type="discrete" tableValues="0 1 0 0 0"/>
    </feComponentTransfer>
    <feFlood flood-color="rgb(255,0,0)" />
    <feComposite operator="in" in2="step1" result="color1" />
    <feComponentTransfer in="SourceAlpha" result="step2">
      <feFuncA type="discrete" tableValues="0 0 1 0 0"/>
    </feComponentTransfer>
    <feFlood flood-color="rgb(255,255,0)" />
    <feComposite operator="in" in2="step2" result="color2" />
    <feComponentTransfer in="SourceAlpha" result="step3">
      <feFuncA type="discrete" tableValues="0 0 0 1 0"/>
    </feComponentTransfer>
    <feFlood flood-color="rgb(0,255,0)" />
    <feComposite operator="in" in2="step3" result="color3" />
    <feComponentTransfer in="SourceAlpha" result="step4">
      <feFuncA type="discrete" tableValues="0 0 0 0 1"/>
    </feComponentTransfer>
    <feFlood flood-color="rgb(0,0,255)" />
    <feComposite operator="in" in2="step4" result="color4" />
    <feMerge>
      <feMergeNode in="color1" />
      <feMergeNode in="color2" />
      <feMergeNode in="color3" />
      <feMergeNode in="color4" />
    </feMerge>
  </filter>
  <rect fill="url(#sourceGradient)" x="50" y="25" width="300" height="50" id="rect" />
  <use xlink:href="#rect" y="100" filter="url(#filter)" />
</svg>

在抗锯齿边缘的这两个 alpha 值之间插入替换颜色

我不确定我是否理解这一点,但 type="table" 用于组件传输会导致持续扩展。合并后的结果在大多数地方的不透明度低于 1,因此您需要一些最后的步骤来再次提升它。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="200">
  <linearGradient id="sourceGradient" x1="0" x2="1" y1="0" y2="0">
    <stop style="stop-color:#000000;stop-opacity:0" offset="0" />
    <stop style="stop-color:#000000;stop-opacity:1" offset="1" />
  </linearGradient>
  <filter id="filter" x="0" y="0" width="1" height="1">
    <feComponentTransfer in="SourceAlpha" result="step1">
      <feFuncA type="table" tableValues="0 1 0 0 0"/>
    </feComponentTransfer>
    <feFlood flood-color="rgb(255,0,0)" />
    <feComposite operator="in" in2="step1" result="color1" />
    <feComponentTransfer in="SourceAlpha" result="step2">
      <feFuncA type="table" tableValues="0 0 1 0 0"/>
    </feComponentTransfer>
    <feFlood flood-color="rgb(255,255,0)" />
    <feComposite operator="in" in2="step2" result="color2" />
    <feComponentTransfer in="SourceAlpha" result="step3">
      <feFuncA type="table" tableValues="0 0 0 1 0"/>
    </feComponentTransfer>
    <feFlood flood-color="rgb(0,255,0)" />
    <feComposite operator="in" in2="step3" result="color3" />
    <feComponentTransfer in="SourceAlpha" result="step4">
      <feFuncA type="table" tableValues="0 0 0 0 1"/>
    </feComponentTransfer>
    <feFlood flood-color="rgb(0,0,255)" />
    <feComposite operator="in" in2="step4" result="color4" />
    <feMerge result="merged">
      <feMergeNode in="color1" />
      <feMergeNode in="color2" />
      <feMergeNode in="color3" />
      <feMergeNode in="color4" />
    </feMerge>
    <feComponentTransfer  in="SourceAlpha" result="capped">
      <feFuncA type="discrete" tableValues="0 1 1 1 1"/>
    </feComponentTransfer>
    <feComposite operator="atop" in="merged" in2="capped" />
  </filter>
  <rect fill="url(#sourceGradient)" x="50" y="25" width="300" height="50" id="rect" />
  <use xlink:href="#rect" y="100" filter="url(#filter)" />
</svg>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 2012-08-04
    • 2016-04-06
    • 1970-01-01
    • 2013-02-27
    • 2016-09-27
    • 1970-01-01
    相关资源
    最近更新 更多