将一个背景图片(.png)添加到SVG圆形形状中。

51

这是否可行?以下是我尝试过的内容,但它完全用黑色填充了圆形。

<svg id='vizMenu' width="700" height="660">
    <defs>
        <filter id="dropshadow" height="130%">
            <feGaussianBlur in="SourceAlpha" stdDeviation="2"/> 
            <feOffset dx="0.5" dy="0.8" result="offsetblur"/> 
            <feMerge>
                <feMergeNode/>
                <feMergeNode in="SourceGraphic"/>
            </feMerge>
        </filter>
    </defs>
    <circle id='top' filter="url(#dropshadow)" cx="180" cy="120" r="80" stroke="#2E2E2E" stroke-width="2" fill="url('images/word-cloud.png')"/>
    <circle id='bottom' filter="url(#dropshadow)" cx="500" cy="300" r="80" stroke="#2E2E2E" stroke-width="2" fill="url('images/word-cloud.png')"/>
    <circle id='extra' filter="url(#dropshadow)" cx="180" cy="560" r="80" stroke="#2E2E2E" stroke-width="2" fill="#ffffff"/>
</svg>

1
哈哈,这些人很多,我觉得他们在电脑后面感觉很强大。祝你解决问题顺利。 - Cleverbot
我没有给你点反对,但也许是因为你发布的代码是用于添加阴影效果而不是填充图片! - methodofaction
没关系,填充功能不起作用的代码已经离屏了。在发布代码时,请尽量将其缩减到最小。 - methodofaction
目前无法直接从填充或描边属性引用PNG。您需要将图像包装在模式元素中,并定义其平铺和缩放方式。请参见Duopixel的答案。 - Erik Dahlström
2
可能是用背景图填充SVG路径元素的重复问题。 - Erik Dahlström
5个回答

44

通过SVG Patterns实现了SVG元素的图像填充...

<svg width="700" height="660">
  <defs>
    <pattern id="image" x="0" y="0" patternUnits="userSpaceOnUse" height="1" width="1">
      <image x="0" y="0" xlink:href="url.png"></image>
    </pattern>
  </defs>
  <circle id='top' cx="180" cy="120" r="80" fill="url(#image)"/>
</svg>

也可以使用SVG过滤器实现,但是Pattern是更自然的选择。 - Erik Dahlström
6
我们能否停止使用 "fill" 来复制 PNG 图像并将其显示在背景中?在这种情况下,它会不断重复出现在背景中。是否可能只显示一次图案?我的意思是不要平铺... - vicky
3
闭合定义标签缺失。 - dev4life
我已经为你关闭了那个标签。 - Michael Mullany
3
有没有一种方法可以停止这个模式不断重复,而是让它按比例缩放适应? - Jeff Paquette
2
这种技术根本不起作用。你必须使用Teo Inke答案中的方法。即使这样,当您尝试以任何方式进行转换时(即缩放等),它也会出现问题。 - Tersosauros

32

嗯,我不能用被接受的答案让它工作。这是我最终的做法:

    <svg width="100" height="100">
      <defs>
        <pattern id="image" patternUnits="userSpaceOnUse" height="100" width="100">
          <image x="0" y="0" height="100" width="100" xlink:href="http://i.imgur.com/7Nlcay7.jpg"></image>
        </pattern>
      </defs>
      <circle id='top' cx="50" cy="50" r="50" fill="url(#image)"/>
    </svg>

如果您想自定义大小,请使用以下内容作为比例参考:

x = 您的首选大小

<svg width=">2x" height=">2x">
  <defs>
    <pattern id="image" patternUnits="userSpaceOnUse" height=">2x" width=">2x">
      <image x="0" y="0" height="2x" width="2x" xlink:href="http://i.imgur.com/7Nlcay7.jpg"></image>
    </pattern>
  </defs>
  <circle id='top' cx="x" cy="x" r="x" fill="url(#image)"/>
</svg>

(此比例只适用于正方形图像)


3
即使按照被接受的答案,我也无法让它正常工作。感谢你的回答。 - Nav
4
如何停止它的重复播放?而且它的缩放不正确。 - Astronaut
发现将图像居中于圆形的关键是在<pattern>上设置xy属性为宽度/高度的一半(如上所示的“x”)。仍然没有找到为什么<pattern>的宽度/高度必须超过图像尺寸以消除边框(填充?)的解释,但这也是我的经验。 - brichins

16

图像重复问题得到了适当的解释(感谢AmeliaBR)

简而言之:使用objectBoundingBoxpreserveAspectRatio概念!

<svg height = "10%" width = "10%">
  <defs>
    <pattern id = "attachedImage" height = "100%" width = "100%"            
                   patternContentUnits = "objectBoundingBox">
       <image xlink:href = "url.png" preserveAspectRatio = "none" 
              width = "1" height = "1"/>
    </pattern>
  </defs>
<circle cx = "50%" cy = "50%" r = "35%" fill = "url(#attachedImage)"/>
</svg>

13

我知道这是一个老问题,但我使用了一个滤镜来叠加图片。上面的解决方案对我没有用,因为它似乎会瓦片化,而且缩放也有问题。相反,我使用了这个,希望能帮助其他人。

<svg width="700" height="660">
    <filter id="this_image" x="0%" y="0%" width="100%" height="100%">
        <feImage xlink:href="test_image.png"/>
    </filter>
    <circle filter="url(#this_image)" cx="180" cy="120" r="80" />
</svg>

4
功能正常,但图片呈矩形?应该让圆形完全填充背景图像。 - Ankit Balyan

2
这是我的解决方案,与此不同的是它不使用 patternUnits="userSpaceOnUse" ,而且你需要指定图像元素的期望宽度和高度。
<defs>
    <pattern id="{some name}" x="0" y="0" width="1" height="1">
        <image href="{image url}" x="0" y="0" width="{desired width}" height="{desired height}"></image>
    </pattern>
</defs>

我尝试了你的解决方案,但对我没有用。我看不到图片。我使用调试,它清楚地显示图片位置良好,但没有任何显示,我验证了我的图片是有效的。 - Thierry

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