使用背景图像填充 SVG 路径元素,无需平铺或缩放

Fill SVG path element with a background image without tiling or scaling

我想做一些非常类似于 Fill SVG path element with a background-image 的事情,除了那里提供的解决方案将平铺图像以填充整个背景区域。我不想要那个。如果图像没有填满整个高度或整个宽度,那么我只是希望它在路径形状内居中,就这样吧。如果我尝试通过更改 height/width 属性来限制行为,则渲染只会缩放图像,直到它至少填充一个维度。

我想这种行为在某种程度上是有道理的,因为它使用了模式。我可以看到我想要的并不是真正的 "pattern" 本身。我只想按原样在我的形状中间拍一张图像,而不是用它制作图案。但是,我确实希望我的 SVG 路径定义的形状边界能够在图像的大小超出这些边界时切断图像的渲染。除了为 fill 属性使用模式之外,我不知道还有什么可以得到这种行为,正如在该问题的答案中所做的那样。

在一个类似的问题中:Add a background image (.png) to a SVG circle shape,最底部的用户似乎表示他使用过滤器而不是模式来实现我想要实现的目标。但是,当我尝试这样做时,在渲染过程中没有考虑实际形状。渲染图像时不考虑形状边界,这似乎没什么用。

在 SVG 中是否有任何方法可以获得类似图案的背景图像行为,但实际上没有将图像平铺成图案?

只需使模式的 xywidthheight 与路径的边界框匹配即可。您可以在这里分别使用“0”、“0”、“1”和“1”,因为 patternUnits 默认为 objectBoundingBox,因此单位是相对于边界框表示的。然后使图案中的图像也具有路径边界框的 widthheight。不过这一次,您需要使用 "real" 尺寸。

图像将自动在图案中居中,因为 <image> 的默认值 preserveAspectRatio 完全符合您的要求。

<svg width="600" height="600">
  
  <defs>
      <pattern id="imgpattern" x="0" y="0" width="1" height="1">
        <image width="120" height="250"
               xlink:href="http://lorempixel.com/animals/120/250/"/>
      </pattern>
  </defs>
  
  
  
  <path fill="url(#imgpattern)" stroke="black" stroke-width="4"
        d="M 100,50 L 120,110 150,90 170,220 70,300 50,250 50,200 70,100 50,70 Z" />

</svg>