SVG模糊滤镜边缘伪影问题

5
当我对SVG图像应用模糊滤镜时,它会使边缘变得稍微透明(请参见左侧示例)。我想要的是在不产生这种伪影的情况下进行模糊处理(请参见右侧示例)。
我通过一种方法解决了这个问题:只需复制相同的翻转图像并将它们放置在四个方向上。
是否有更好的方法?
请注意,我不能仅仅将图像放大5-10%;大小必须与原始图像相同。
以下是我的SVG代码:
...
<filter id="blur">
 <feGaussianBlur in="SourceGraphic" stdDeviation="4"></feGaussianBlur>
</filter>
...
<g filter="url(#blur)">
  <image xlink:href="cathedral.jpg"></image>
</g>

enter image description here

1个回答

12

这是一个不错的技巧,用feComponentTransfer增加边缘的不透明度来产生清晰的边框,但它也要求你将过滤器剪裁到过滤元素的大小(使用过滤元素中的过滤器大小属性) - 如果你不这样做,你会看到新的不透明模糊和黑色背景溢出原始图像。

<filter id="blur" x="0%"
 y="0%" width="100%" height="100%">
 <feGaussianBlur in="SourceGraphic" stdDeviation="4"/>
  <feComponentTransfer>
      <feFuncA type="discrete" tableValues="1 1"/>
   </feComponentTransfer>
</filter>
...
<g filter="url(#blur)">
  <image xlink:href="cathedral.jpg"></image>
</g>
如果您没有方形输入(比如说您的照片是圆形),那么您需要使用feComposite "in"将输出剪切到输入区域,而不是使用滤镜尺寸。但是现在feComposites的速度有点慢,并且还不能作为CSS滤镜的一部分使用,因此上述方法对于方形输入更可取。
请注意,这种方法无法处理具有可变不透明度/alpha通道的图像——它会将所有内容转换为100%不透明度。
另一种变体是使用feColorMatrix来执行相同的操作,一些浏览器似乎已经对此操作进行了GPU加速,因此它可能比feComponentTransfer更快。
<filter id="blur" x="0%"
 y="0%" width="100%" height="100%">
 <feGaussianBlur in="SourceGraphic" stdDeviation="4"/>
 <feColorMatrix type="matrix"  values="1 0 0 0 0
                                       0 1 0 0 0 
                                       0 0 1 0 0 
                                       0 0 0 0 1"/>
</filter>
...
<g filter="url(#blur)">
  <image xlink:href="cathedral.jpg"></image>
</g>

它似乎不起作用。请参见此处:http://jsbin.com/vugojiju/1/edit 我放了同样的图像在后面以说明问题 - 模糊图像的透明边缘。 - Plastic Rabbit
1
你必须在添加componentTransfer之前关闭feGaussianBlur标签。在我的代码中,我使用一个自闭合的<feGaussianBlur/>标签。而在你的版本中,你将componentTransfer放在一对开启和关闭的feGaussian标签内。因此,它正在忽略componentTransfer。 - Michael Mullany
有一个错别字:在第一行,x="0%应该有一个闭合的双引号。除此之外,这个黑客技巧很棒! - montecruiseto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接