Javascript svg to png

gustavohenke / svg2png.js

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

var svg = document . querySelector ( «svg» ) ;
var svgData = new XMLSerializer ( ) . serializeToString ( svg ) ;
var canvas = document . createElement ( «canvas» ) ;
var ctx = canvas . getContext ( «2d» ) ;
var img = document . createElement ( «img» ) ;
img . setAttribute ( «src» , «data:image/svg+xml;base64,» + btoa ( svgData ) ) ;
img . onload = function ( )
ctx . drawImage ( img , 0 , 0 ) ;
// Now is done
console . log ( canvas . toDataURL ( «image/png» ) ) ;
> ;

Is there a way to convert PNG to SVG?

Not that I’m aware of.
PNG is a raster image type, while SVG is a vector.

Note that currently this solution does not work in Firefox. Chrome seems to support this ok. I’m also thinking that the onload function should probably be defined before setting the image src .

To have the image not be cropped, you just need to set the size of the convas, which you can do based on the size of the svg.

Just put this immediately after var canvas = .

 var svgSize = svg.getBoundingClientRect(); canvas.width = svgSize.width; canvas.height = svgSize.height; 

My onload function is not getting called here and even the image is not getting displayed..please suggest an option

Using this to draw a d3pie pie chart to the canvas just renders an empty object.
However, I can easily append img to a container in the document and it’s loaded as a SVG resource with no problems.

Edit: Decided to use canvg and pass svgData to it instead of creating an img out of it and it works ! But I still don’t understand why the original code didn’t work.

converting svg to data url is working but when I try to render it to canvas it’s not showing images that used in svg. any idea I have already add required attrs to svg

 var html = d3.select("svg") .attr(< 'xmlns': 'http://www.w3.org/2000/svg', 'xmlns:xmlns:xlink': 'http://www.w3.org/1999/xlink', version: '1.1' >) .node().parentNode.innerHTML; var imgsrc = 'data:image/svg+xml;base64,'+ btoa(html); d3.select('canvas').attr('width',_canvasWidth).attr('height',_canvasHeight); var canvas = document.querySelector("canvas"), context = canvas.getContext("2d"); var image = new Image; image.src = imgsrc; image.onload = function() < context.drawImage(image, 0, 0); var canvasdata = canvas.toDataURL("image/png"); var pngimg = ''; d3.select("#pngdataurl").html(pngimg); var a = document.createElement("a"); a.download = "export_"+Date.now()+".png"; a.href = canvasdata; document.body.appendChild(a); a.click(); >; 

IE11 (probably others too) have some issues with SVG namespaces — I don’t know if it is the Raphael to blame or something else. One solution is to fix the namespaces yourself:

you will have some weird stuff like:

xmlns:NS1="" NS1:xmlns:xlink="http://www.w3.org/1999/xlink" 
xmlns:xlink="http://www.w3.org/1999/xlink" 

and fix the xlinks accordingly

@philfreo , I found your function useful, but it was still partially cut off, so as a hack, I did this to ensure it wasn’t cut off. Won’t work in all cases. Just a heads up that getBoundingClientRect() doesn’t seem to always work.

 canvas.width = svgSize.width * 2; canvas.height = svgSize.height * 2; 

By the way, this gist is a lifesaver!

Here’s what i’m using. Works fine in Chrome but not on Firefox. Any ideas?

function svg_to_png(container) < var wrapper = document.getElementById(container); var svg = wrapper.querySelector("svg"); if (typeof window.XMLSerializer != "undefined") < var svgData = (new XMLSerializer()).serializeToString(svg); >else if (typeof svg.xml != "undefined") < var svgData = svg.xml; >var canvas = document.createElement("canvas"); var svgSize = svg.getBoundingClientRect(); canvas.width = svgSize.width; canvas.height = svgSize.height; var ctx = canvas.getContext("2d"); var img = document.createElement("img"); img.setAttribute("src", "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(svgData))) ); img.onload = function() < ctx.drawImage(img, 0, 0); var imgsrc = canvas.toDataURL("image/png"); var a = document.createElement("a"); a.download = container+".png"; a.href = imgsrc; a.click(); >; > 

@Guillemp
put your img.setAttribute(. ) after img.onload

@Guillemp
you should append in the body!

Seems a little odd to base64 encode it. I went with

var img = new Image() img.src = "data:image/svg+xml;utf8," + svgData

@toastal Using utf8 didn’t seem to work. Did it work for you? I am Using Chrome.

var svg = document.querySelector( «svg» );
var svgData = new XMLSerializer().serializeToString( svg );

var canvas = document.createElement( «canvas» );
var svgSize = svg.getBoundingClientRect();
canvas.width = svgSize.width;
canvas.height = svgSize.height;
var ctx = canvas.getContext( «2d» );

var img = document.createElement( «img» );
img.setAttribute( «src», «data:image/svg+xml;base64,» + btoa( svgData ) );

img.onload = function() ctx.drawImage( img, 0, 0 );

// Now is done console.log( canvas.toDataURL( "image/png" ) ); 

Worked with this code. but for some SVG files it is showing «NETWORK ERROR». Can u help?

When I convert SVG to PNG it only export graph plot not graph data to PNG .
Please Advice or suggest any solution.

I’m trying to export angular-d3-charts to PDF as an image but the chart is not complete the x-axis are hidden as it’s not inline style is there any workaround to solve this .

You save my life. @Guillemp This code works well! Thank you very much!

I used snap JS to draw svg, here what I do:

var s = Snap('#svg_id'); var svg = document.querySelector( "#svg_id" ); var svgData = new XMLSerializer().serializeToString( svg ); var canvas = document.createElement( "canvas" ); canvas.width = 1500; canvas.height = 1450; var ctx = canvas.getContext( "2d" ); var img = document.createElement( "img" ); img.setAttribute( "src", s.toDataURL()); console.log(s.toDataURL()); img.onload = function() < ctx.drawImage( img, 0, 0 ); console.log( canvas.toDataURL( "image/png" ) ); var imgsrc = canvas.toDataURL( "image/png" ); var a = document.getElementById("download_png"); a.download = "filename.png" a.href = imgsrc; >; 

Here’s what i’m using. Works fine in Chrome but not on Firefox. Any ideas?

function svg_to_png(container) < var wrapper = document.getElementById(container); var svg = wrapper.querySelector("svg"); if (typeof window.XMLSerializer != "undefined") < var svgData = (new XMLSerializer()).serializeToString(svg); >else if (typeof svg.xml != "undefined") < var svgData = svg.xml; >var canvas = document.createElement("canvas"); var svgSize = svg.getBoundingClientRect(); canvas.width = svgSize.width; canvas.height = svgSize.height; var ctx = canvas.getContext("2d"); var img = document.createElement("img"); img.setAttribute("src", "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(svgData))) ); img.onload = function() < ctx.drawImage(img, 0, 0); var imgsrc = canvas.toDataURL("image/png"); var a = document.createElement("a"); a.download = container+".png"; a.href = imgsrc; a.click(); >; > 

var svg = document.querySelector( «svg» );
var svgData = new XMLSerializer().serializeToString( svg );

var canvas = document.createElement( «canvas» );
var svgSize = svg.getBoundingClientRect();
canvas.width = svgSize.width;
canvas.height = svgSize.height;
var ctx = canvas.getContext( «2d» );

var img = document.createElement( «img» );
img.setAttribute( «src», «data:image/svg+xml;base64,» + btoa( svgData ) );

img.onload = function() ctx.drawImage( img, 0, 0 );

// Now is done console.log( canvas.toDataURL( "image/png" ) ); 

>;

Worked with this code. but for some SVG files it is showing «NETWORK ERROR». Can u help?

Here’s what i’m using. Works fine in Chrome but not on Firefox. Any ideas?

function svg_to_png(container) < var wrapper = document.getElementById(container); var svg = wrapper.querySelector("svg"); if (typeof window.XMLSerializer != "undefined") < var svgData = (new XMLSerializer()).serializeToString(svg); >else if (typeof svg.xml != "undefined") < var svgData = svg.xml; >var canvas = document.createElement("canvas"); var svgSize = svg.getBoundingClientRect(); canvas.width = svgSize.width; canvas.height = svgSize.height; var ctx = canvas.getContext("2d"); var img = document.createElement("img"); img.setAttribute("src", "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(svgData))) ); img.onload = function() < ctx.drawImage(img, 0, 0); var imgsrc = canvas.toDataURL("image/png"); var a = document.createElement("a"); a.download = container+".png"; a.href = imgsrc; a.click(); >; > 

Источник

tatsuyasusukida / !README-javascript-svg-png.md

Video thumbnail: How to convert SVG to PNG with JavaScript

This article describes how to convert SVG to PNG with frontend JavaScript. The related resources are as follows.

The workflow is as follows.

Run the following command in the terminal to prepare for coding.

mkdir javascript-svg-png cd javascript-svg-png touch index.html main.js

Open index.html in the editor and enter the following content.

Open main.js in the editor and enter the following content.

Open index.html in your browser. For macOS, it is convenient to run the following command in the terminal.

Make sure you see the PNG image in the Output PNG Image section of your web page.

It looks like index.html is opened in the browser. The heading of the web page is

The sample source code contains the following sentence to convert SVG text to base64.

const svgDataBase64 = btoa(unescape(encodeURIComponent(svgData)))

I was curious about how it would be converted to base64 through the process, so I looked it up. The following is the SVG text before conversion.

Next, the following is the execution result of encodeURIComponent(svgData) .

%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22240%22%20height%3D%22240%22%20id%3D%22input%22%3E%0A%20%20%20%20%20%20%20%20%3Ccircle%20cx%3D%22120%22%20cy%3D%22120%22%20r%3D%2290%22%20fill%3D%22%23888888%22%2F%3E%0A%20%20%20%20%20%20%3C%2Fsvg%3E 

Next, the following is the execution result of unescape(encodeURIComponent(svgData)) .

Finally, the following is the execution result of btoa(unescape(encodeURIComponent(svgData))) .

PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNDAiIGhlaWdodD0iMjQwIiBpZD0iaW5wdXQiPgogICAgICAgIDxjaXJjbGUgY3g9IjEyMCIgY3k9IjEyMCIgcj0iOTAiIGZpbGw9IiM4ODg4ODgiLz4KICAgICAgPC9zdmc+ 

btoa is a function that converts a string to Base64, but you cannot pass a string containing non-ASCII characters as an argument. Therefore, I use the encodeURIComponent function and the unescape function to convert non-ASCII characters to ASCII characters. For example, the Japanese hiragana «あ» is 0xE3 0x81 0x82 in UTF-8, so the result of encodeURIComponent (‘あ’) is %E3%81%82 (By the way, in the case of encode (‘あ’) Will raise a SyntaxError exception). On the other hand, the unescape function recognizes %E3 %81 %82 as 3 characters, so the result of unescape(‘%E3%81%82′) is’ã\x81\x82’.

I understand that the JavaScript btoa(unescape(encodeURIComponent(text))) is similar to the Buffer.from(text).toString(‘base64′) in Node.js. So is it possible to convert from base64 to text with decodeURIComponent(escape(atob(base64))) (same as Buffer.from(base64,’base64’). toString() in Node.js? Is it something like that?). When I executed the code below, it was evaluated as «A», so it seems to be correct.

decodeURIComponent(escape(atob(btoa(unescape(encodeURIComponent('あ'))))))

I didn’t always understand the reason and just copied and pasted it, so I got smarter because I had time to investigate. I hope this article helps anyone with similar questions. Thank you for reading!

Источник

Конвертируем svg to png

Иногда появляется необходимость сохранить svg в png средствами браузера. К сожалению, браузер не имеет волшебного api, который позволил бы это сделать без различных хаков. Что же делать, если все таки хочется добиться желаемого?

Первая идея, которая мне пришла в голову, сделать это через canvas, который имеет метод toDataURL(‘image/png’);
Итак, я написал простенький скрипт: 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); >; 

secureError

Суть скрипта проста: я преобразовывал svg в dataUri, загружал его через image, рисовал картинку на canvas и превращал в png. Казалось, цель достигнута, и можно расслабится. Этот подход сработал в Firefox и Chrome, но открыв во всеми нами любимом браузере IE, я получил замечательную ошибку:

Дело в том, что IE считает, что картинка загружена с другого хоста. К сожалению, установить origin для dataUri не получится. Собственно, описание правил можно найти здесь: https://html.spec.whatwg.org/multipage/scripting.html#security-with-canvas-elements. Можно было, конечно, проксировать svg через сервер, и тогда все бы сработало, но хотелось чисто клиентское решение.

И тут я вспомнил про замечательную библиотеку canvg. С помощью этой библиотеки я рисую svg на canvas, а далее поступаю как в первом варианте: беру toDataURL(«image/png») . Получился такой незамысловатый код: 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], ); saveAs(blob, 'export_' + Date.now() + '.png'); 

Тут стоит сказать, что еще я использовал библиотеку FileSaver для вызова диалогового окна сохранения.
Вот и все, мы добились желаемого результата.

Стоит отметить один нюанс — я задался вопросом сохранения svg в png, когда писал плагин для экспорта tauCharts. Так как стили в svg задаются из внешнего файла, чтобы добиться максимально подобия с исходным svg, я вставляю inline style в svg. И получаем вот такой результат.

Надеюсь, статья окажется полезной для вас и сохранит ваше время.

Источник

Читайте также:  Реставрация сумки из кожи питона
Оцените статью