将CSS过滤器转换为SVG过滤器

时间:2016-04-18 11:08:43

标签: html css svg svg-filters css-filters

我根据需要在<img />元素上使用CSS过滤器。

例如

filter: brightness(1) contrast(67%) saturate(250%) grayscale(0%) invert(0%) hue-rotate(330deg) sepia(40%) blur(0px);

我的目标是将相同的过滤器属性应用于SVG文件中的<image />标记。

然而像

这样的事情
<g style="-webkit-filter: contrast(67%) saturate(250%);">
    <image xlink:href="image.jpg" />
</g>

<image xlink:href="image.jpg" style="-webkit-filter: contrast(67%) saturate(250%) sepia(40%)"/>

不起作用。

所以我很可能必须将CSS过滤器组合为SVG过滤器。

在webplatform.org上,我发现了SVS对特定CSS过滤效果的重新反应,例如:

然后我尝试将生成的过滤器与feMerge合并。

<filter id="clip_1-filter-90117969876336">
    <feComponentTransfer in="SourceGraphic" result="brightness-filter">
      <feFuncR type="linear" slope="22"></feFuncR>
      <feFuncG type="linear" slope="22"></feFuncG>
      <feFuncB type="linear" slope="22"></feFuncB>
    </feComponentTransfer>

    <feComponentTransfer in="brightness-filter" result="contrast-filter">
      <feFuncR type="linear" slope="-15" intercept="7"></feFuncR>
      <feFuncG type="linear" slope="-15" intercept="7"></feFuncG>
      <feFuncB type="linear" slope="-15" intercept="7"></feFuncB>
    </feComponentTransfer>

    <feColorMatrix in="contrast-filter" result="grayscale-filter" type="matrix" values="
       1 0 0 0 0
       0 1 0 0 0
       0 0 1 0 0
       0 0 0 1 0"></feColorMatrix>

    <feComponentTransfer in="SourceGraphic" result="invert-filter">
      <feFuncR type="table" tableValues="0 1"></feFuncR>
      <feFuncG type="table" tableValues="0 1"></feFuncG>
      <feFuncB type="table" tableValues="0 1"></feFuncB>
    </feComponentTransfer>

    <feMerge>
      <feMergeNode in="grayscale-filter"></feMergeNode>
    </feMerge>
    </filter>

然而,结果远非预期。

将CSS过滤器转换为SVG的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

您的过滤器看起来大致正确,但我怀疑您的feComponentTransfer in属性中存在拼写错误。我想你可能意味着:

<feComponentTransfer in="grayscale-filter" result="invert-filter">

请注意,如果每个阶段的输入都是最后一个阶段的输出,则不需要使用resultin

此外,如果只有一个节点,则不需要最终的feMerge

&#13;
&#13;
<svg width="5cm" height="5cm" viewBox="0 0 500 500">
  <defs>
  <filter id="clip_1-filter-90117969876336">
    <feComponentTransfer in="SourceGraphic">
      <feFuncR type="linear" slope="22"></feFuncR>
      <feFuncG type="linear" slope="22"></feFuncG>
      <feFuncB type="linear" slope="22"></feFuncB>
    </feComponentTransfer>

    <feComponentTransfer>
      <feFuncR type="linear" slope="-15" intercept="7"></feFuncR>
      <feFuncG type="linear" slope="-15" intercept="7"></feFuncG>
      <feFuncB type="linear" slope="-15" intercept="7"></feFuncB>
    </feComponentTransfer>

    <feColorMatrix type="matrix" values="
       1 0 0 0 0
       0 1 0 0 0
       0 0 1 0 0
       0 0 0 1 0"></feColorMatrix>

    <feComponentTransfer>
      <feFuncR type="table" tableValues="0 1"></feFuncR>
      <feFuncG type="table" tableValues="0 1"></feFuncG>
      <feFuncB type="table" tableValues="0 1"></feFuncB>
    </feComponentTransfer>
  </filter>
  </defs>

  <image xlink:href="http://lorempixel.com/500/500/"
         width="500" height="500" filter="url(#clip_1-filter-90117969876336)"/>
  <rect fill="none" stroke="blue"  
        x="1" y="1" width="498" height="498"/>
</svg>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

你的feColorMatrix目前是一个单位矩阵,而不是灰度过滤器,你的第三个feComponentTransfer也是一个身份变换(它(0 1)保留所有颜色 - 你可能意味着(1 0)。)

我不知道上次合并的目的是什么。您想将反演结果与灰度相混合吗?或者你想要反转你的灰度。

查看web platform doc for feColorMatrixan intro article I wrote for .NET mag即可开始使用。在那之后,我建议阅读罗伯特在评论中链接的规范。