Converting SVG to PNG without knowing the width and height

995 views Asked by At

I am trying to convert an SVG to a PNG image using the canvas as the "proxy". I can get it to work in Chromium, but not in Firefox. It seams that I need a width and height defined in the SVG, but in my case the SVG does not have width and height attributes. When the SVG is displayed in the browser the size depends on the size of the container/window.

The SVGs are converted to PNG successfully, but this one shell SVG.

Here is the JSFiddle: https://jsfiddle.net/8mqtLw6p/

var img = new Image();
var svg = new Blob([svgString], {
  type: "image/svg+xml;charset=utf-8"
});
var url = DOMURL.createObjectURL(svg);
img.onload = function() {
  ctx.drawImage(img, 0, 0);
  var png = canvas.toDataURL("image/png");
  var mg = document.createElement("img");
  mg.setAttribute("src", png);
  document.body.appendChild(canvas);
  document.body.appendChild(mg);
  DOMURL.revokeObjectURL(png);
};
img.setAttribute("src", url);
1

There are 1 answers

0
chrwahl On BEST ANSWER

To be able to draw a bitmap image it needs a size (width and height). If the SVG does not have a size specified and you would like to copy it as it is rendered in the browser you can use getBoundingClientRect() to get the width and height.

Now, that you SVG is rather big I just replaced all the paths with a circle and modified the viewBox a bit.

let svg01 = document.getElementById('Capa_1');
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let img01 = document.getElementById('img01');

let BCR = svg01.getBoundingClientRect();
svg01.setAttribute('width', BCR.width);
svg01.setAttribute('height',BCR.height);

var xmlSerializer = new XMLSerializer();
var svgString = xmlSerializer.serializeToString(svg01);

var svg = new Blob([svgString], {
  type: "image/svg+xml;charset=utf-8"
});
var url = URL.createObjectURL(svg);

let img = new Image();

img.addEventListener('load', e => {
  URL.revokeObjectURL(e.target.src);
  canvas.width = e.target.width;
  canvas.height = e.target.height;
  ctx.drawImage(e.target, 0, 0);
  img01.src = canvas.toDataURL('image/png');
});
img.src = url;
<h3>The SVG:</h3>
<svg id="Capa_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 60">
  <style type="text/css">.st0 { fill: rgb(222, 83, 81); }.st1 { fill: rgb(23, 89, 149); }.st2 { fill: none; stroke: rgb(222, 83, 81); stroke-width: 2; stroke-miterlimit: 10; }.st3 { fill: rgb(33, 37, 88); }.st4 { fill: rgb(177, 223, 239); }.st5 { fill: rgb(255, 255, 255); }</style>
  <circle class="st1" cx="40" cy="30" r="25" />
</svg>
<hr>
<canvas id="canvas"></canvas>
<div>
  <img id="img01" />
</div>