部分透明的svg滤镜合成

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

我正在尝试将一种形状复合到另一种形状上。顶层是一组具有不透明度的笔画。底部只是洪水填充。

问题是我需要笔画保留其原始颜色和不透明度 - 不要与洪水混合。

我遇到的问题是,当我用洪水中的不透明度“剪切”笔画时,它会剪切颜色,但不会剪切不透明度。因此,当我用不透明度的笔划替换剪切时,不透明度不再正确。

我有一个有效/笨重的解决方案,我必须创建两组相同的笔画 - 一组不透明,一组是实心的。实体用于执行切割,然后我可以选取不透明的并覆盖它。

<svg width="120" height="120" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
      <defs>
        <!-- create duplicate strokes, one with opacity and one without -->
        <path id="strokes" d="M20,10 L60,60 M50,10 L90,90" stroke="rgb(112,48,160)" stroke-width="15" stroke-opacity="0.5" fill="none" />
        <path id="strokesSolid" d="M20,10 L60,60 M50,10 L90,90" stroke="rgb(112,48,160)" stroke-width="15" fill="none" />
        <filter id="filter" color-interpolation-filters="sRGB">
          <feFlood flood-color="blue" x="0" y="0" width="100" height="100" result="flood" />
          <feImage xlink:href="#strokesSolid" x="0" y="0" width="100" height="100" result="lines2" />
          <!-- cut the solid stroke -->
          <feComposite in="flood" in2="lines2" operator="out" result="cut" />
          <!-- composite the opacity stroke -->
          <feImage xlink:href="#strokes" x="0" y="0" width="100" height="100" result="lines" />
          <feComposite in="lines" in2="cut" operator="over" result="final" />
        </filter>
      </defs>
      <rect x="15" y="15" width="105" height="105" fill="white" stroke="red" stroke-width="2" id="backdrop" />
      <rect x="20" y="20" width="100" height="100" fill="rgb(0, 128, 0)" id="compare" />
      <rect width="100" height="100" filter="url(#filter)" id="partialTransparentShape" />
    </svg>

红色轮廓和绿色矩形背面只是用于测试目的,以证明这会产生正确的结果(将 SVG 保存为文件,在 Inkscape 中打开,导出为 .png,在 Paint.net 中打开,使用颜色选择器来证明颜色/不透明度)。

是否有更直接的方法来实现此目的,而不必创建两条相同的带不透明度和不带不透明度的路径?

svg svg-filters
1个回答
0
投票

在使用 feComposite/out 之前,只需使用额外的 feColorMatrix 将线条的不透明度加倍

<svg width="120" height="120" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
      <defs>
        <path id="strokes" d="M20,10 L60,60 M50,10 L90,90" stroke="rgb(112,48,160)" stroke-width="15" stroke-opacity="0.5" fill="none" />

        <filter id="filter" color-interpolation-filters="sRGB">
          <feFlood flood-color="blue" x="0" y="0" width="100" height="100" result="flood" />
          <feImage xlink:href="#strokes" x="0" y="0" width="100" height="100" />
          <!-- cut the solid stroke -->
          <feColorMatrix type="matrix" values="1 0 0 0 0 
                                               0 1 0 0 0 
                                               0 0 1 0 0 
                                               0 0 0 2 0"/>
          <feComposite in="flood" operator="out" result="cut" />
          <!-- composite the opacity stroke -->
          <feImage xlink:href="#strokes" x="0" y="0" width="100" height="100" result="lines" />
          <feComposite in="lines" in2="cut" operator="over" result="final" />
        </filter>
      </defs>
      <rect x="15" y="15" width="105" height="105" fill="white" stroke="red" stroke-width="2" id="backdrop" />
      <rect x="20" y="20" width="100" height="100" fill="rgb(0, 128, 0)" id="compare" />
      <rect width="100" height="100" filter="url(#filter)" id="partialTransparentShape" />
    </svg>

© www.soinside.com 2019 - 2024. All rights reserved.