17

I know that I can set a svg file as the src of an HTML img element like this:

<img src="mySVG.svg"/>

but can I somehow set a dynamic SVG element as the src of an img?

<svg id="mySVGElement">
    ...
</svg>

<img src="?"/>
Patrick Klug
  • 14,056
  • 13
  • 71
  • 118

2 Answers2

24

You can do this with JavaScript:

var svg = document.querySelector('svg'),
    img = document.querySelector('img');

setImageToSVG(img,svg);

function setImageToSVG(img,svg){
  var xml = (new XMLSerializer).serializeToString(svg);
  img.src = "data:image/svg+xml;charset=utf-8,"+xml;
}​

If your SVG element is dynamic (changing) then you would need to re-run this code each time the SVG element changed.

Demo: http://jsfiddle.net/3PfcC/


Alternatively, here's a demo showing @Robert's answer, using another <svg> element to reference the first, live:

Demo: http://jsfiddle.net/3PfcC/3/

<svg id="src" xmlns="http://www.w3.org/2000/svg" …>
  <!-- Your SVG here -->
</svg>

<svg xmlns="http://www.w3.org/2000/svg" xmlns:x="http://www.w3.org/1999/xlink" …>
  <use x:href="#src" x="80" y="30" width="100" height="100" />
</svg>

The demo also shows that you can resize and otherwise transform the referenced SVG document, and that the reference is live: changes to the original are immediately reflected in the <use>.

Klesun
  • 12,280
  • 5
  • 59
  • 52
Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • neat. thanks. accepted. Unfortunately it appears that the first version (data uri) doesn't work with IE10 which is my target platform so it doesn't seem to be possible to set it to an img without creating a file first. – Patrick Klug Aug 01 '12 at 23:07
  • thanks for that, works nicely. I toyed around and noticed the source SVG element doesn't need any attributes as is done in the fiddle, at least in Chrome. The Destination SVG attributes will take care of scaling and clipping. – tim Apr 04 '13 at 01:28
  • Doesn't work on FireFox (57.0) (something with the image src doesn't parse well), I will update if I'll find a solution. – Ezra Steinmetz Jan 28 '18 at 23:57
  • 2
    It seems to be that FireFox has problems with SVG with an hashtag (like here, fill="#900"), as it reads it as the end of the svg, we need to replace it with "%23". This one works on Chrome and FireFox: http://jsfiddle.net/taaf9ah7/2/ – Ezra Steinmetz Jan 29 '18 at 00:27
  • 2
    In your demo, the image is a broken image. This used to work, and now does not in Chrome. It seems like Chrome changed something about SVGs as new Image().src, it used to fire my .onload handler and now instead fires my .onerror handlers... no idea why this changed suddenly – OG Sean Feb 14 '19 at 04:31
  • 2
    On year 2020, the solution does not work on Chrome or Firefox img.src = "data:image/svg+xml;base64,"+btoa(xml); fixes it (added as an aswer below) – tru7 Jan 28 '20 at 13:05
16

This updates the accepted answer from Phrogz (8 years after it!)

The sample does not work on Chrome or Firefox (the image appears broken) changing to

  img.src = "data:image/svg+xml;base64,"+btoa(xml);

I am not sure of the reason why the original stopped working but this may help someone landing here.

tru7
  • 6,348
  • 5
  • 35
  • 59