首页 > 解决方案 > 两个过滤的 SVG 文件的合成

问题描述

我正在尝试为印刷电路板实施视觉“差异”策略。目的是用蓝色突出“新”添加,用红色突出设计(已删除)的旧部分。我有两个 b&w svg 文件,每个文件都代表电路板单层的特定修订。这些是以编程方式生成的。它们看起来像示例 svg 的 png 图像- 我无法直接上传 .svg,但这里有几个示例;

3c9fec_F_Cu.svg

75d8f4_F_Cu.svg

我已经应用了两个单独的 feColorMatrix 过滤器,一个过滤器用于版本 1 和另一个版本 2,然后将两个过滤后的图像放置在绝对位置,以便它们相互重叠,在一个<div>.

这在 Chrome 中有效,但在其他浏览器中失败(已尝试过 Safari 和 Firefox)。

Chrome 中的结果(所需):

我试图直接应用 feColorMatrix 过滤器并合并结果文件,但这在任何浏览器中都不起作用。

我当前成功的代码(适用于 Chrome):

.gallery {
  border: 1px solid #ccc;
}

.gallery:hover {
  border: 1px solid #777;
}

.gallery img {
  width: 100%;
  height: auto;
}
<div class="gallery">
<svg width="1123px" height="794px" viewBox="50 0 600 400" xmlns="http://www.w3.org/2000/svg" version="1.1">
                <defs>
                    <filter id="f1" x="0%" y="0%" width="100%" height="100%">
                        <feColorMatrix result="original" id="c1" type="matrix" values="1   0   0   0   0
                                                    0   1   0   1   0
                                                    0   0   1   1   0
                                                    0   0   0   1  0 " />
                    </filter>
                    <filter id="f2" x="0%" y="0%" width="100%" height="100%">
                        <feColorMatrix result="original" id="c2" type="matrix" values="1   0   0   1   0
                                            0   1   0   0   0
                                            0   0   1   0   0
                                            0   0   0   .5   0" />
                    </filter>

                </defs>
            <image x="0" y="0" width="100%" filter="url(#f1)" xlink:href="../../75d8f4/ThermocoupleLogger-F_Cu.svg" style="position:absolute;" />    
            <image x="0" y="0" width="100%" filter="url(#f2)" xlink:href="../../3c9fec/ThermocoupleLogger-F_Cu.svg" style="position:absolute;" />
            </svg>
    </div>

我对 feMerge 的替代尝试:

<div class="gallery">
<svg width="1123px" height="794px" viewBox="50 0 600 400" xmlns="http://www.w3.org/2000/svg" version="1.1">
                <defs>
                    <filter id="f1" x="0%" y="0%" width="100%" height="100%">
                    <feColorMatrix xlink:href="../../75d8f4/ThermocoupleLogger-F_Cu.svg" result="one" type="matrix" 
                                    values="1   0   0   0   0
                                            0   1   0   1   0
                                            0   0   1   1   0
                                            0   0   0   1  0 " />
                    </filter>

                    <filter id="f2" x="0%" y="0%" width="100%" height="100%">
                    <feColorMatrix xlink:href="../../3c9fec/ThermocoupleLogger-F_Cu.svg" result="two" type="matrix"
                                    values="1   0   0   1   0
                                            0   1   0   0   0
                                            0   0   1   0   0
                                            0   0   0   .5   0" />
                    </filter>

                    <filter id="composite">
                        <feMerge>
                        <feMergeNode in="one"/>
                        <feMergeNode in="two"/>
                        </feMerge>
                    </filter>

                </defs>

<g filter="url(#composite)"></g>

</svg>
</div>

我会重视任何可以让我在一定程度上实现跨浏览器兼容性的建议。

标签: htmlsvgsvg-filters

解决方案


您的第一个版本大部分是正确的 - 但直接向您的图像标签添加一个高度属性 - SVG 对尺寸很挑剔,Chrome 经常接受它不应该接受的东西。img 和 image 标签是不同的元素,因此 height:auto 不适用于您的图像标签。此外 - 适用于 SVG 子元素的 CSS 样式数量有限 - 如果有疑问,请坚持使用 SVG 属性。并删除position: absolute- 默认情况下SVG中的定位是绝对的。

由于多种原因,第二个版本无法正常工作。feColorMatrix 不接受 xlink:href 作为输入 - 您必须先使用 feImage 将外部文件导入过滤器并为其添加result属性。in然后,您可以在feColorMatrix的属性中引用结果。过滤器只能result在同一过滤器中引用 a - 因此从过滤器引用onetwo来自id=composite过滤器将不起作用。最后,过滤一个空g标签是行不通的——它没有任何尺寸,所以过滤面积为零。所以......使用你第一次尝试的这个调整版本。

.gallery {
  border: 1px solid #ccc;
}

.gallery:hover {
  border: 1px solid #777;
}

.gallery img {
  width: 100%;
  height: auto;
}
<div class="gallery">
<svg width="1123px" height="794px" viewBox="50 0 600 400" xmlns="http://www.w3.org/2000/svg" version="1.1">
                <defs>
                    <filter id="f1" x="0%" y="0%" width="100%" height="100%">
                        <feColorMatrix result="original" id="c1" type="matrix" values="1   0   0   0   0
                                                    0   1   0   1   0
                                                    0   0   1   1   0
                                                    0   0   0   1  0 " />
                    </filter>
                    <filter id="f2" x="0%" y="0%" width="100%" height="100%">
                        <feColorMatrix result="original" id="c2" type="matrix" values="1   0   0   1   0
                                            0   1   0   0   0
                                            0   0   1   0   0
                                            0   0   0   .5   0" />
                    </filter>

                </defs>
            <image x="0" y="0" height="100%" width="100%" filter="url(#f1)" xlink:href="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/beacon.svg"  />    
            <image x="0" y="0" height="100%" width="100%" filter="url(#f2)" xlink:href="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/adobe.svg"  />
            </svg>
    </div>

您还可以使用 feComposite 的 xor 运算符来做一个更优雅的版本。鼠标悬停查看效果。

svg :hover {
  filter: url(#diff);
}
<svg width="1600px" height="800px" viewBox="0 0 1600 800">
<defs>
  <filter id="diff" x="20%" y="0%" width="80%" height="100%" >
    <feColorMatrix type="matrix" values="0 0 0 0 0  0 0 0 0 0   0 0 0 0 1   0 0 0 1 0" result="blue-original"/>
    <feImage x="-100" y="0" width="800" height="600" xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/32648/SVG-Test%201.svg">
    </feImage>
       <feColorMatrix type="matrix" values="0 0 0 0 1  0 0 0 0 0   0 0 0 0 0   0 0 0 1 0"/> 
    <feComposite operator="xor" in="blue-original"/>
  </filter>
  </defs>



<image  xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/32648/SVG-test2.svg" x="-100" y="0" width="800" height="600" preserveAspectRatio="xMinYMin slice"/>
  
  <image  xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/32648/SVG-Test%201.svg" x="500" y="0" width="800" height="600" preserveAspectRatio="xMinYMin slice"/>
  
</svg>


推荐阅读