51

Is this possible? The following is what I tried but it completely fills the circle with black.

<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>
David Newcomb
  • 10,639
  • 3
  • 49
  • 62
icanc
  • 3,499
  • 3
  • 35
  • 45
  • 1
    Haha there are lots of them, I think they feel strong hiding behind their computers. Good luck with your problem – Cleverbot Jul 16 '12 at 01:40
  • I didn't downvote you, but perhaps it's because the code you posted is for applying a dropshadow, not an image fill! – methodofaction Jul 16 '12 at 08:04
  • Nevermind, the non-working code for fill is offscreen. When posting code try to reduce it to the minimum. – methodofaction Jul 16 '12 at 08:12
  • 2
    possible duplicate of [Fill SVG path element with a background-image](http://stackoverflow.com/questions/3796025/fill-svg-path-element-with-a-background-image) – Erik Dahlström Jul 16 '12 at 13:58
  • You can't reference a PNG directly from a fill or stroke attribute at the moment. You'll have to wrap the image in a pattern element and define how it should be tiled and scaled. See the answer from [Duopixel](http://stackoverflow.com/a/11500364/109374). – Erik Dahlström Jul 16 '12 at 10:42

5 Answers5

44

An image fill for an svg element is achieved through SVG Patterns...

<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>
Michael Mullany
  • 30,283
  • 6
  • 81
  • 105
methodofaction
  • 70,885
  • 21
  • 151
  • 164
  • It is possible to do with SVG filters too, but patterns is the natural answer. – Erik Dahlström Jul 16 '12 at 10:36
  • 6
    Can we stop replicate png display in background using fill. In this case it will keep replicating the image in background. Is it possible to display pattern only once? I mean no tiling... – vicky Feb 13 '13 at 15:46
  • 3
    closing defs tag missing – dev4life Sep 27 '13 at 16:05
  • I closed that tag for you – Michael Mullany Nov 22 '13 at 00:58
  • 3
    Is there a way to stop the pattern from repeating, having it scale to fit instead? – Jeff Paquette Sep 07 '15 at 13:12
  • 2
    This technique doesn't work at all. You HAVE to use the method in [Teo Inke's](http://stackoverflow.com/users/2105657/teo-inke) [answer](http://stackoverflow.com/questions/11496734/add-a-background-image-png-to-a-svg-circle-shape#answer-24128191). And even then, that breaks when you try to transform in any way (i.e. scaling, etc). – Tersosauros Jun 25 '16 at 16:43
32

Well, I couldn't make it work with the accepted answer. This is how I ended up doing it:

    <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>

If you want to customize the size, use this as a scale reference:

x = yourPreferredSize

<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>

(This scale works for squared images)

Alexandr_TT
  • 13,635
  • 3
  • 27
  • 54
Teo Inke
  • 5,928
  • 4
  • 38
  • 37
  • 3
    Even I couldn't get it working with the accepted answer. Thanks for your answer. – Nav Oct 27 '14 at 11:45
  • 4
    How do I stop it from repeating? also it's not scalling properlly – Astronaut Oct 27 '14 at 15:19
  • DIscovered that the key to centering my image in a circle was to set `x` and `y` attributes on the `` to half the width/height ("x" above). Still haven't found an explanation for why the `'s` width/height have to exceed the image's dimensions to eliminate borders (padding?), but that has been my experience as well. – brichins Nov 29 '16 at 22:36
16

Image repetition problem solved with proper explanation (Thanks to AmeliaBR)

TL;DR: The concept of objectBoundingBox and preserveAspectRatio are used!

<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>
Community
  • 1
  • 1
Photon Khan
  • 441
  • 5
  • 5
13

I know this is an old question, but I used a filter to overlay the image. The above solution didn't work for me because of scaling and it seemed like the images was tiled. I used this instead, I hope it will help others as well.

<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>
Arian Faurtosh
  • 17,987
  • 21
  • 77
  • 115
2

This is my solution, the differences are that this doesn't use the patternUnits="userSpaceOnUse" and that you specify the desired width and height of the image element.

<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>
Lukeus_Maximus
  • 443
  • 1
  • 3
  • 10
  • I tried your solution but it didn't work for me. I couldn't see the image. I use the debugging and it clearly showed me the image was in good position but nothing to display and I verified that my image was an valid image. – Thierry Jan 17 '17 at 19:34