Save inline SVG as JPEG/PNG/SVG

Tim Rideyourbike picture Tim Rideyourbike · Jan 30, 2015 · Viewed 42.5k times · Source

I have an inline SVG in my html, and I need to be able to save this as either a JPEG, PNG or SVG.

I have tried a few different methods with converting the SVG to canvas and then converting to JPEG, but I haven't been able to get these working.

Here is an example of my inline SVG.

Also, not all the elements need to be exported, as some of the options the user has is to remove the top corner numbers.

I would like for when it's been converted to download straight to the browser.

Answer

Ciro Costa picture Ciro Costa · Jan 30, 2015

Nowadays this is pretty simple.

The basic idea is:

  1. svg to canvas
  2. canvas to dataUrl
  3. trigger download from dataUrl

it actually works outside of stackoverflow snippet

var btn = document.querySelector('button');
var svg = document.querySelector('svg');
var canvas = document.querySelector('canvas');

function triggerDownload (imgURI) {
  var evt = new MouseEvent('click', {
    view: window,
    bubbles: false,
    cancelable: true
  });

  var a = document.createElement('a');
  a.setAttribute('download', 'MY_COOL_IMAGE.png');
  a.setAttribute('href', imgURI);
  a.setAttribute('target', '_blank');

  a.dispatchEvent(evt);
}

btn.addEventListener('click', function () {
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');
  var data = (new XMLSerializer()).serializeToString(svg);
  var DOMURL = window.URL || window.webkitURL || window;

  var img = new Image();
  var svgBlob = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});
  var url = DOMURL.createObjectURL(svgBlob);

  img.onload = function () {
    ctx.drawImage(img, 0, 0);
    DOMURL.revokeObjectURL(url);

    var imgURI = canvas
        .toDataURL('image/png')
        .replace('image/png', 'image/octet-stream');

    triggerDownload(imgURI);
  };

  img.src = url;
});
<button>svg to png</button>

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="200" height="200">
  <rect x="10" y="10" width="50" height="50" />
  <text x="0" y="100">Look, i'm cool</text>
</svg>

<canvas id="canvas"></canvas>

Regarding the downloading part, you can set up a filename and etc etc (although not in this example). Some days ago i answered a question on how to download a specific portion of HTML from the given page. It might be useful regarding the downloading part: https://stackoverflow.com/a/28087280/2178180

update: now letting you specify the filename