使用SVG过滤器替换一种颜色

时间:2017-01-13 16:20:27

标签: canvas svg svg-filters

是否可以拍摄IMG照片并将一种确切的颜色替换为另一种颜色,比如说#fff为#000,保持所有其他颜色不变? SVG过滤器的颜色矩阵可能会有所帮助吗?

1 个答案:

答案 0 :(得分:8)

这对Canvas来说是微不足道的。它也可以用SVG,但它是复杂的。以下方法适用于传统的完全不透明图像。首先,使用长ComponentTransfer将每个通道中的每个非匹配颜色值转换为零,并将每个匹配颜色值转换为1(256个成员tableValues数组中唯一“1”的索引应与您的r,g和b替换值)。然后,使用颜色矩阵将除了生成的白色像素之外的所有内容的零点清零。您将结果用作具有目标颜色的feFlood的遮罩,并将结果合并到原始图形的顶部。例如 - 以下代码用红色替换特定颜色 - rgb(87,78,29)。

    <svg width="800px" height="600px" viewBox="0 0 800 600">
      <defs>
      <filter id="color-replace" x="0%" y="0%" width="100%" height="100%" color-interpolation-filters="sRGB">
    
        <!--Replace rgb(87,78,29) with red-->
        <feComponentTransfer>
          <feFuncR type="discrete" tableValues="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"/>
          <feFuncG type="discrete" tableValues="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"/>
          <feFuncB type="discrete" tableValues="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"/>
        </feComponentTransfer>
        
     <feColorMatrix type="matrix" values="1 0 0 0 0 
                                          0 1 0 0 0
                                          0 0 1 0 0 
                                          1 1 1 1 -3" result="selectedColor"/>
      
          <feFlood flood-color="red"/>
          <feComposite operator="in" in2="selectedColor"/>
          <feComposite operator="over" in2="SourceGraphic"/>  
      </filter>
      </defs>
    <g filter="url(#color-replace)">
      <rect  x="50" y="50" height="100" width="100" fill="rgb(86,77,28)"/>
        <rect  x="250" y="50" height="100" width="100" fill="rgb(86,77,29)"/>
        <rect  x="450" y="50" height="100" width="100" fill="rgb(86,78,29)"/>
        <rect  x="50" y="250" height="100" width="100" fill="rgb(87,77,29)"/>
        <rect  x="250" y="250" height="100" width="100" fill="rgb(87,78,29)"/>
        <rect  x="450" y="250" height="100" width="100" fill="rgb(87,78,30)"/>
        <rect  x="50" y="450" height="100" width="100" fill="rgb(88,78,30)"/>
        <rect  x="250" y="450" height="100" width="100" fill="rgb(88,79,29)"/>
          <rect  x="450" y="450" height="100" width="100" fill="rgb(88,79,30)"/>
      </g>
    </svg>