如何制作SVG散点过滤器?

时间:2018-10-31 12:44:19

标签: svg svg-filters

我尝试将精确的形状转换为一系列散点,这些散点在源图像的中间具有更高的密度。

Example: White Circle on Black Background → Messier 92(很抱歉,我没有足够的声誉来嵌入图像)

因此,仍然可以识别圆形以外的其他形状。这是我能做的最好的事情:

我将这种效果称为 scatter 过滤器。请告诉我您是否有更好的名字。

<svg height='100' width='100'>
  <filter id="cluster" filterUnits="userSpaceOnUse">
    <feGaussianBlur in="SourceGraphic" result='blurred' stdDeviation="10" />
    <feTurbulence type="turbulence" baseFrequency="9" numOctaves="4" result="turbulence" /> 
    <feDisplacementMap in2="turbulence" in="blurred" scale="10" xChannelSelector="R" yChannelSelector="G"  />
  </filter>
  <rect x='0' y='0' height='100' width='100' fill='black' />
  <circle cx='50' cy='50' fill='white' r='30' filter='url(#cluster)' />
</svg>

基本上是花哨的模糊。随着scalefeDisplacementMap的增加,结果看起来更好。

<svg height='100' width='100'>
  <filter id="cluster" filterUnits="userSpaceOnUse">
    <feGaussianBlur in="SourceGraphic" result='blurred' stdDeviation="10" />
    <feTurbulence type="turbulence" baseFrequency="9" numOctaves="4" result="turbulence" /> 
    <feDisplacementMap in2="turbulence" in="blurred" scale="50" xChannelSelector="R" yChannelSelector="G"  />
  </filter>
  <rect x='0' y='0' height='100' width='100' fill='black' />
  <circle cx='50' cy='50' fill='white' r='30' filter='url(#cluster)' />
</svg>

但这也会使图像移位。我可以撤消吗?还是首先不做?也许使用了feDisplacementMap以外的东西?

1 个答案:

答案 0 :(得分:0)

您的过滤器的主要问题是它的baseFrequency非常高-您需要将这些频率调低。分形滤波器的feTurbulence类型fractalNoise比湍流更好。只要您的置换图位于通道0.5的中心,图像就不应平均以x / y置换。如果您有明亮或黑暗的位移图(feTurbulence并非如此),这只是一个问题。最后-更高的位移比例将为您提供想要的尖锐外观-像这样。

要获得所需的确切外观,可能需要花费大量的尝试和错误。这是指向阴影的滤镜编辑器的链接,可能会给您一些想法https://codepen.io/mullany/pen/sJopz

<svg height="220px" width="260px" viewBox="0 0 800 600">
  <defs>
    <filter id="scatter">
      <feTurbulence baseFrequency=".2" type="fractalNoise" numOctaves="3"/>
      <feDisplacementMap in="SourceGraphic" xChannelSelector="G" yChannelSelector="B" scale="300"/>
      <feComposite operator="in" in2="finalMask"/>
    </filter>
    </defs>
  
  <g filter="url(#scatter)">
  <polyline points="10,10  10,300, 300,400" transform="translate(60 60)" fill="blue"/>
  
  <polyline points="500,10  110,300, 300,400" transform="translate(260 60)" fill="red"/>
  </g>
</svg>