📜 ⬆️ ⬇️

Convert svg to png

Sometimes it becomes necessary to save svg in png using browser tools. Unfortunately, the browser does not have a magic api that would allow it to be done without different hacks. What to do if you still want to achieve the desired?

The first idea that came to my mind is to do it through canvas, which has a toDataURL('image/png'); method toDataURL('image/png');
So, I wrote a simple script: jsfiddle , github :

 var html = document.querySelector("svg").parentNode.innerHTML; var imgsrc = 'data:image/svg+xml;base64,' + btoa(html); var canvas = document.querySelector("canvas"), context = canvas.getContext("2d"); canvas.setAttribute('width', 526); canvas.setAttribute('height', 233); var image = new Image; image.src = imgsrc; image.onload = function () { context.drawImage(image, 0, 0); var canvasdata = canvas.toDataURL("image/png"); var a = document.createElement("a"); a.textContent = "save"; a.download = "export_" + Date.now() + ".png"; a.href = canvasdata; document.body.appendChild(a); canvas.parentNode.removeChild(canvas); }; 


The essence of the script is simple: I converted svg to dataUri, loaded it through image, drew a picture on the canvas and turned it into png. It seemed that the goal was achieved, and you can relax. This approach worked in Firefox and Chrome, but opened in all of our favorite browser IE, I got a wonderful error:
secureError
The fact is that IE believes that the image is downloaded from another host. Unfortunately, setting origin for dataUri will fail. Actually, the description of the rules can be found here: https://html.spec.whatwg.org/multipage/scripting.html#security-with-canvas-elements . It was possible, of course, to proxy svg through the server, and then everything would work, but I wanted a purely client solution.
')
And then I remembered the wonderful canvg library. With this library, I draw svg on canvas, and then I act as in the first version: I take toDataURL("image/png") . It turned out such a simple code: github :

 var svg = document.querySelector('svg'); var canvas = document.createElement('canvas'); canvas.height = svg.getAttribute('height'); canvas.width = svg.getAttribute('width'); canvg(canvas, svg.parentNode.innerHTML.trim()); var dataURL = canvas.toDataURL('image/png'); var data = atob(dataURL.substring('data:image/png;base64,'.length)), asArray = new Uint8Array(data.length); for (var i = 0, len = data.length; i < len; ++i) { asArray[i] = data.charCodeAt(i); } var blob = new Blob([asArray.buffer], {type: 'image/png'}); saveAs(blob, 'export_' + Date.now() + '.png'); 


It is worth saying that I also used the FileSaver library to invoke the save dialog.
That's all, we have achieved the desired result.

It is worth noting one nuance - I wondered about saving svg to png when I wrote a plugin for tauCharts export. Since the styles in svg are set from an external file, in order to achieve the maximum similarity with the original svg, I insert the inline style in svg. And we get this result .

I hope the article will be useful for you and save your time.

Source: https://habr.com/ru/post/254973/


All Articles