使用SVG使用混合滤镜(更具体地说)

时间:2013-12-10 11:31:41

标签: svg colors vector-graphics blending svg-filters

我有一个使用SVG尝试实现的效果的参考图像。

Bitmap reference image

在Photoshop中,可以通过使用100%不透明度并将混合模式设置为“乘法”来实现效果

颜色的十六进制值为:

红色:#EA312F,蓝色:#3A5BA6和重叠区域:#35111F

我尝试了一些使用SVG滤镜的方法来达到类似的效果,但我很难理解混合模式如何计算值。

SVG attempts to match original graphic

  1. 原始Photoshop位图
  2. SVG仅使用形状无过滤器
  3. SVG在垂直条上使用乘法滤镜
  4. SVG使用垂直条上的乘法滤镜和不透明度
  5. 您可以在this JSBin http://jsbin.com/iPePuvoD/1/edit

    中查看每个SVG代码

    我真的很难理解匹配垂直条蓝色和重叠区域颜色的最佳方法。

    这些形状中的每一个我也想使用像http://snapsvg.io/这样的库进行动画制作,所以我希望完全依赖过滤器,而不是裁剪或其他操作来达到预期效果 - 但是接受建议。

    实际上,最终尝试的SVG(4.)是这样的:

    <svg viewBox="0 0 96 146" version="1.1" id="f-multiply-opacity" preserveAspectRatio="xMinYMin meet">
      <defs>
        <filter id="f_multiply" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
          <feBlend in="SourceGraphic" mode="multiply"/>
          <feBlend in="SourceGraphic" mode="multiply"/>
        </filter>
      </defs>
      <g id="f_shape">
        <rect x="0" y="0" width="96" height="32" fill="#EA312F" />
        <rect x="0" y="50" width="96" height="32" fill="#EA312F" />
        <rect x="0" y="50" width="32" height="96" opacity="0.8" fill="#3A5BA6" filter="url(#f_multiply)" />
      </g>
    </svg>
    

    非常感谢有关这方面的一些建议,我已经在SVG上找到了一些很好的资源,但是这个领域似乎仍然很难获得好的信息。

    谢谢!

3 个答案:

答案 0 :(得分:7)

这不适用于多个级别。 Feblend需要两个输入而不是一个。你将sourcegraphic与什么混合在一起?如果要与背景混合,则需要使用backgroundImage作为in2。如果要与其他形状混合,则必须使用feimage将该形状导入过滤器。下一个问题BackgroundImage目前仅适用于IE,并且feImage仅适用于Chrome和Safari中的引用形状(更新:您可以将引用的形状转换为内联SVG数据URI,这将跨浏览器工作)。

如果您只使用彩色矩形,那么您可以使用feflood在滤镜内生成它们并将它们混合在那里。如下所示:

<svg x="800px" height="600px" viewBox="0 0 200 100" version="1.1" id="f-multiply-opacity" preserveAspectRatio="xMinYMin meet">
  <defs>
    <filter id="f_multiply" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
      <feFlood x="0" y="0" width="96" height="32" flood-color="#EA312F" result="a"/>
      <feFlood x="0" y="50" width="96" height="32" flood-color="#EA312F" result="b"/>
      <feFlood rect x="0" y="50" width="32" height="96" flood-opacity="0.8" flood-color="#3A5BA6" result="c"/>
      <feBlend in="a" in2="b" result="ab" mode="multiply"/>
      <feBlend in="ab" in2="c" mode="multiply"/>
     </filter>
  </defs>
  <g id="f_shape">
    <rect filter="url(#f_multiply)" x="0" y="0" width="200" height="200"/>
  </g>
</svg>

更新: 在过滤器中使用形状的跨平台方式是将它们编码为feImage中的SVG / XML数据URI。这是跨浏览器支持的(尽管它使代码很难阅读。)

答案 1 :(得分:5)

请参阅Compositing and Blending Level 1 spec。它允许指定在渲染Web内容(包括svg)时使用的合成和混合。通过切换运行时标志,它可以在许多浏览器中测试,请参阅here for instructions。有关mix-blend-mode的最新浏览器支持,请参阅caniuse

<svg>
  <style>
    circle { mix-blend-mode: multiply; }
  </style>
  <circle cx="40" cy="40" r="40" fill="#EA312F"/>
  <circle cx="80" cy="40" r="40" fill="#3A5BA6"/>
</svg>

作为jsfiddle here

答案 2 :(得分:0)

对于所有feBlend模式,结果不透明度计算如下:

qr = 1 - (1-qa)*(1-qb)

对于下面的合成公式,以下定义适用:

cr = Result color (RGB) - premultiplied 
qa = Opacity value at a given pixel for image A 
qb = Opacity value at a given pixel for image B 
ca = Color (RGB) at a given pixel for image A - premultiplied 
cb = Color (RGB) at a given pixel for image B - premultiplied 
The following table provides the list of available image blending modes:

图像混合模式计算结​​果颜色的公式

normal  cr = (1 - qa) * cb + ca
multiply    cr = (1-qa)*cb + (1-qb)*ca + ca*cb
screen  cr = cb + ca - ca * cb
darken  cr = Min ((1 - qa) * cb + ca, (1 - qb) * ca + cb)
lighten cr = Max ((1 - qa) * cb + ca, (1 - qb) * ca + cb)

来自http://www.w3.org/TR/SVG/filters.html#feBlendElement