Save off an SVG with images

I want to make an SVG that includes another SVG icon I have as an <image> so I can save off the colored result. But, when I try to export it, I only see the rectangle, not the image. Is there a way I can make an SVG that contains an <image>, and export the results?

Notebook

Thanks. Always learning,
Zach

A quick (and dirty) solution is to pass the icon’s code as a data url:

testExport = html`<svg width=400 height=400>
  <rect width=400 height=400 fill="${color}"></rect>
  <image 
    class="fill-mainImg"
    x="0" 
    y="0" 
    width="${mainImg.width * 0.3}" 
    height="${mainImg.height * 0.3}" 
    href="data:image/svg+xml;utf8,${await FileAttachment("mainImg.svg").text().then(d => d.replace(/^.*?<svg /, "<svg ").replace(/"/g, '&quot;'))}" 
  />
</svg>
`

I had to remove some elements at the beginning of the file (the xml declaration etc), and convert any " to &quot;. ymmv

1 Like

Interesting. So you can use .text() with a file attachment of an SVG to get at some of the codestuffs. I’d have to say I don’t understand the syntax of the href you are making, but can confirm this works nicely. Any insight into how this works and why this is different than referencing the src from the image() version?

@zachbogart You can read more about data URLs here:

3 Likes

The crucial difference in this case is that image.url is just a pointer to a remote resource (which stays on observable’s servers), at the address static.observableusercontent.com/files/004d5688321…
whereas the data url contains the actual data (contents) of the image, without having to look it up on the net.

1 Like

Excellent, thanks!