exupero / savesvgaspng Goto Github PK
View Code? Open in Web Editor NEWSave SVGs as PNGs from the browser.
License: MIT License
Save SVGs as PNGs from the browser.
License: MIT License
Good day! This is regards to saveSvgAsPng program that you made. I have some few questions. First, when I am trying your demo, I can't save a svg file as png and an error has been log to the console saying that "Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. saveSvgAsPng.js:34img.onload".
Another, as you said, to make the program work I must add saveSvgAsPng(document.getElementById("diagram"), "diagram.png", 3);
What does the following means? Is a diagram id is a div? And why is there a diagram.png? What is the purpose of the file? Hoping for your response, thank you!
I'm really happy to be using this library but I'm trying to use the font face embedding work around referenced in issue #24 but I can't seem to get it to work. The base64 embedded fonts are working in the browser.
Here is the @font-face rule;
@font-face {
font-family: 'Open Sans Embedded';
src: url(data:font/opentype;charset=utf-8;base64,<data>);
src: url(data:font/opentype;charset=utf-8;base64,<data>) format('embedded-opentype'),
url(data:application/font-woff;charset=utf-8;base64,<data>) format('woff'),
url(data:application/font-ttf;charset=utf-8;base64,<data>) format('truetype'),
url(data:image/svg+xml;charset=utf-8;base64,<data>) format('svg');
font-weight: 400;
font-style: normal;
}
And my SVG font is defined in my stylesheet;
#mysvg {
font-family: 'Open Sans Embedded';
}
... but no dice. Am I missing something?
I tried it on an SVG I generated with D3. All the primitives shapes seemed to come out ok but the foreign objects do not show up. Is there something I can do about this?
With an svg that sets a viewBox, I am seeing the resulting png that gets exported is clipped and only partially rendered in the image.
(for example): '<svg width="100%" viewBox="0 0 300 225">...</svg>'
I played around with the code a little and was able to workaround this with the snippet below:
var viewBoxWidth = el.viewBox.baseVal.width == 0 ? width : el.viewBox.baseVal.width;
var viewBoxHeight = el.viewBox.baseVal.height == 0 ? height : el.viewBox.baseVal.height;
clone.setAttribute("viewBox", "0 0 " + viewBoxWidth + " " + viewBoxHeight);
I'm not well versed enough with the svg to understand if this is the right way to go about this, although it appears to work in my case. Would be interested to hear what others think and if you'd consider merging a PR with this patch...
I'm using highcharts to render charts and using saveSvgAsPng to download snapshots, what I've found is that highcharts includes a namespace in the markup it produces, this causes saveSvgAsPng to silently fail.
I've made changes locally to fix this (essentially test to see if the namespace is already set), I can make a pull request if you're interested.
Trying to export a c3js chart, first I'm creating a rect filled with white color before the chart so it doesn't render it grey, but as you can see, there are these black areas which display as white on the HTML
Issue: Having linked SVG or PNG files inside the svg source results in incomplete export of the source. Using the following svg, only the linked png image is saved upon export, with no other elements or images. using online file sources also produce security error.
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" id="mySVG" viewBox="-100 -90 200 200" height="600" width="700">
<defs>
<marker refY="0.5" refX="0.0" markerHeight="4" markerWidth="2" orient="auto" id="head">
<path fill="#D0D0D0" d="M0,0 L0.5,0.5 L0,1 L-0.5,0.5 Z"/>
</marker>
<marker refY="0.6" refX="0.1" markerHeight="4" markerWidth="2" orient="auto" id="tail">
<path fill="white" d="M0 0 V1.3 L0.6 0.6 Z"/>
</marker>
</defs>
<path id="myArrow" marker-start="url(#tail)" marker-end="url(#head)" d="M -66.38265586443396 22.21132594835645 A 70 70 0 0 0 66.38265586443396 22.21132594835645" fill="none" stroke="#D0D0D0" stroke-width="8"/>
<text id="myText" x="-14.999999999999995" y="-80" transform="rotate(0 4.898587196589413e-15,-80)" font-family="Calibri" font-size="8" font-weight="bold" fill="#D0D0D0">text</text>
<image x="60" y="-25" width="50" height="50" xlink:href="http://upload.wikimedia.org/wikipedia/commons/3/30/Vector-based_example.svg"/>
<path id="myArrow" marker-start="url(#tail)" marker-end="url(#head)" d="M 66.38265586443396 -22.211325948356432 A 70 70 0 0 0 -66.38265586443396 -22.211325948356436" fill="none" stroke="#D0D0D0" stroke-width="8"/>
<text id="myText" x="-14.999999999999995" y="80" transform="rotate(180 4.898587196589413e-15,80)" font-family="Calibri" font-size="8" font-weight="bold" fill="#D0D0D0">text</text>
<image x="-110" y="-25.00000000000001" width="50" height="50" xlink:href="http://upload.wikimedia.org/wikipedia/commons/3/30/Vector-based_example.svg"/>
<image x="-25" y="-25" width="50" height="50" xlink:href="http://i.imgur.com/bV5qrz3.png"/>
</svg>
I'm attempting to use the function with a bar chart. Everything converts perfectly except for both the text that labels the tick marks, and the text that labels the legend.
After pulling commit 7872e63 it only downloads empty images with 300x150 resolution.
Hi there,
I am trying to save an SVG with id "timeseriesSVG" to a png.
I use this function call:
saveSvgAsPng(document.getElementById("timeseriesSVG"), "timeseries.png");
The image shows up just fine in the Safari tab. However, the address bar doesn't show a path to the png, it's a large chunk of what I'm assuming is dataURI. Example in this gist.
If I right-click on the image and click Save Image to "Downloads", the image is saved with filename "Unknown" and no extension, no matter what I suggest as a filename in the function call.
If I drag the image to the desktop, then it does get a png extension, but the filename is still "Unknown.png".
Any ideas on what could be going wrong? Or is this expected behaviour and I'm misinterpreting something?
This happens on Safari 8.0.7, on OS X 10.10.4.
if there's a global styling SVG element which sets width
or height
, provided width
or height
attribute gets ignored resulting in a weird scaling @ Safari
Apologies if I'm misunderstanding what's going on here, but I've been having some strange sizing issues with inlineImages()
.
I have a D3 chart with a handful of different svg icons inline. The inlineImages()
function seems to be interpreting the canvas height and width for each icon to be 150 and 300, respectively. The strange thing is, each inline svg image has been explicitly set to 48x48. Once the svg images have been converted to png format, they appear quite a bit smaller as 48x48 islands in the center of a 300x150 png image. See screenshots:
I've found that by setting img.height
and img.width
to 150 inside the inlineImages()
function, then adding an x-offset parameter to ctx.drawImage()
, I'm able to work around this, but am not 100% sure why the issue has arisen in the first place. However, I freely admit that I don't know much about canvas or the toDataURL()
function.
Hello, I've been trying to use
saveSvgAsPng(document.getElementById("printSVG"), "printSVG.png",1)
with the following structure:
SVG called printSVG that contains the "use href" statement to another svg on the page called mapSVG
The image does show in the browser, but when saved, printSVG is blank. I can save the mapSVG just fine using itself. But I want to include a bunch of different svgs on the page arrange them then save the png.
Apologies for the long title, I have a few small issues with this library. I've managed to integrate it about 80% with my project, but am struggling to get the final pieces sorted.
I'm building a tool to wrap up snap.svg into a nice editor, and need to export the built SVG as PNG.
The first issue re. Angular is the same as issue #11 - which I am still having trouble with.
In regards to the other issues, in the case of my project, it is possible an tag could have no href
attribute, which is causing an issue when saveSvgAsPng is looking for images within the SVG element. Additionally, my project allows images to be streamed in as dataURIs, and I am getting an issue where the xlink:href
attribute is repeated. I've done my own debugging with the script to get to the xlink error, a screenshot of trying to load the outputted data URI directly is below.
I'm wondering if it's due to the way snap.svg adds images to the SVG element, and if line 34 of saveSvgAsPng is contributing to the issue.
You can view my project in it's current form here - http://times.github.io/cardkit-v2/#/ - codebase is here - https://github.com/times/cardkit-v2.
I am not sure if this is an issue with ng not conforming to a standard, however, in my project I see...
DOMException: Failed to execute 'querySelector' on 'Element': '[ng:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak, .ng-hide:not(.ng-hide-animate)' is not a valid selector.(…)
I think this is becoming invalid thank to the :
but I am not sure.
IE fails to parse xml image:
XML5661: Non-default namespace declarations must not have an empty URI. Line: 1, Column 335
Checked on latest IE11, but earlier versions are affected too.
I'm trying to use this library with the Nvd3-Angular directive, but I just get an error saying "el.getBBox is not a function". I guess it's because the SVG can't "be found". How can I fix this?
Hi, just tried your lib and immediately hit an error:
Uncaught TypeError: _saveSvgAsPng2.default is not a function
not sure where that is constructed and called. Tried it two ways: via npm, and simply including the js file into my project. Same error both ways. Confirmed I am properly passing in an SVG node and file name.
Any ideas?
thx for sharing the lib.
:Larry
I just get download.png in Chrome.
The functionality works as expected for an svg containing an image element in FireFox but does not work in Chrome. There are no errors in the console when executing the script, but the download dialog box does not show up in Chrome. Any clues as to what the issue could be here ?
Thanks
SecurityError: The operation is insecure.
var rules = sheets[i].cssRules;
saveSvgAsPng.js (line 59)
I'm want to save a svg tag with a d3 chart to an datauri, but it crashes in the process at this line:
104 var css = styles(el, options.selectorRemap);
In the end it results in
DOMException: Failed to execute 'querySelectorAll' on 'Element': '[ng:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak, .ng-hide' is not a valid selector.,
which relates to #11
But why is this still happening? Do I have an old version of the script, because in the above issue it says the code causing this will be deleted?
The svsn tag's content is this:
4813172125293338Jahr040050000100000150000200000250000300000350000Euro0384200Gebundenes VermögenLiquides Vermögen
Best regards,
Kash.
Testing on the sandbox: http://exupero.org/saveSvgAsPng/#custom-font
Is only working for on Linux.
Testing on Linux the png uses the specified font however on Windows and OSx it is defaulting to a serif font.
System information for the Windows test:
Microsoft Windows 10 Pro (10.0.10240)
Firefox: 43.0.1
Chrome: 47.0.2526
it seems that the used method has problems as soon as it encounter any @ rules (exmaple: @page
)
a "better" way would be to inline styles, it seems - also, because styles could be inherited from other selectors, which would not be valid after "separating" the scope via image SVG
Thanks for this Great Script. In chrome it is working nice but In my firefox (version 36) it returns the below error. How to fix it
SecurityError: The operation is insecure.
var rules = sheets[i].cssRules;
Issue: In my SVG I have a circle with some text inside ("new"). When I export as PNG the texts are not appearing. I append my SVG with the styles.
new <style> g.conceptG circle, g.selected circle, g.target circle { fill: #FFFFFF; stroke: #333; stroke-width: 1px;} </style>I tried to replace unescape
with decodeURI
or decodeURIComponent
but it didn't work.
Also I tried to use http://cwestblog.com/2011/05/23/escape-unescape-deprecated/ but it didn't work either.
Hello,
i can't save the svg using the custom font, it don't work neither in the example.
Regards.
As I first tried your script, it worked pretty well. But now, after I edited my svg file a lot, it did stop working. Unfortunately there are no error messages. Can I post here a link to the problematic svg or my website?
It works well in chrome and firefox,but in IE11, it throws an exception:SecurityError
Hello Guys.
I have been using this awesome lib to export some svg images. However now I have a problem trying to use this tool from devices like Apple Ipad (from safari or even chrome).
I'm using this tool with this simple function:
function exportDailyGraph(svgContainerID) {
var svgNode = d3.select(svgContainerID).select("svg").node();
saveSvgAsPng(svgNode, "dailyGraph.png", {scale: 5});
}
From desktops works like a charm... but from for example Ipad, the screen is cleaned and in the url I have only a text with just: "data:,"
Any idea what is the problem?
This is happening when i try to convert the d3 charts created by apache zeppelin:
Uncaught InvalidCharacterError: Failed to execute 'btoa' on 'Window':
The string to be encoded contains characters outside of the Latin1 range.
Thanks for this lib. I am using this for one of my projects. The latest version on npm is 6 months old and there have been a few updates since then on github. I am currently referring to source on github from my package.json
like
"save-svg-as-png": "git://github.com/exupero/saveSvgAsPng.git#gh-pages"
Appreciate if you can publish the latest to npm so others do not depend on source from their package.
If I hard code my svg file into the page and then click Save as Png button it works. If I click the Choose File the svg appears in the page fine. The Preview text still says no file selected. When I click the Save as Png button beside the Choose File button I get an error at line 30 in your script of could not load null (appears in the Chrome console). Is there a fix.
//this works in index.html:
$el.find('.load-target').html(e.target.result);
//this raises an error of 'could not load null' :
svgAsPngUri($el.find('.load-target svg')[0], null, function(uri) {
$el.find('input').hide()
$el.find('.preview').html('<img src="' + uri + '" />');
});
I just got the file from the master branch and I'm seeing this error:
Error: Failed to execute 'querySelectorAll' on 'Element': '[ng:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak, .ng-hide:not(.ng-animate)' is not a valid selector.
Tried this on a svg generated through a directive in angular (in case you were wondering about where does those names come from).
Invoking line:
saveSvgAsPng(document.getElementById("diagram"), "diagram.png", 3);
Hi @exupero,
I'm looking to take advantage of the fix for #51, I've tested it manually and it solves a problem on my project mentioned here Quartz/Chartbuilder#194
Could you update the version number to reflect the change and publish to npm so that we can take care of the bug more automatically?
Thank you
I have my SVG element contained within a <div class="bar-chart-container">
since I have multiple SVG elements on the same page, apply different CSS rules to each, and save them individually.
Therefore, my CSS looks like
.bar-chart-container {
font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
}
.bar-chart-container .x-axis text {
text-rendering: optimizeLegibility;
font-size: 12px;
}
and so on. However, these aren't being applied when I save as a PNG. Previously, I noticed that dom.querySelectorAll(...)
would return an empty array (because the clone SVG element doesn't know it's a child of .bar-chart-container
?). I tried it with your latest commit (6c25e57) and it obviously still doesn't work.
Am I doing something wrong? I was thinking of either adding some type of prefix option to the styles(dom)
method or maybe adding classes to the clone (may not work)?
Was wondering if you had any suggestions or insight on how to solve my problem?
I set up a jsFiddle for testing purposes.
if (isExternal(sheets[i].href)) {
console.warn("Cannot include styles from other hosts: "+sheets[i].href);
continue;
}
That code keeps external stylesheets from being parsed. However, if you use the following, they can be parsed. I've tested in Chrome and read reports that say it works in FF as well.
The key is to make sure the server serving the CSS provides proper cross origin headers. Thankfully, many CDNs for popular libraries do this by default.
Hi, I'm trying to use this library to download my graph visualization as a PNG. In my case, I have two types of coloring for the edges -- one where it is interpolated between the colors of the nodes it connects and the other where it is gray.
For the interpolation effect, I am creating several svg linear gradients and applying the appropriate one for each edge using the url() for the stroke property. When I try to download a network with interpolated edges, it doesn't download the edges, I can only see the nodes in the image.
In the case of non interpolated edges, the stroke is gray and that gets downloaded correctly. Could you please give me some tips on how to fix this?
Given a SVG tag like:
<svg width="100%" ...>...</svg>
This code will get the width as 100 pixels instead of the real width:
width = parseInt(clone.getAttribute('width') ||
box.width ||
clone.style.width ||
window.getComputedStyle(el).getPropertyValue('width'));
Because parseInt("100%")
is 100. I have a patch enhancing the options
parameter so you can explicitly give a width/height but I'm not sure this is how you will like to handle this issue.
I'm trying to use this library to download a chart created with Angular.js, and I keep getting this error saying:
Uncaught SyntaxError: Unexpected end of input VM14371:1
I can't figure out what causes this error, or how to fix it, please help me.
Hey,
This plugin looks awesome, but unfortunately I've not been able to get it working.
I have the following code generated by d3:
<div id="breakdown-chart">
<svg id="fish" width="340" height="340">
<g id="pieChart" transform="translate(170,170)">
<path fill="#d5dadc" d="M9.797174393178826e-15,-160A160,160 0 0,1 125.09303719488477,-99.75836829739735L53.16454080782603,-42.397306526393876A68,68 0 0,0 4.1637991171010006e-15,-68Z">
</path>
<path fill="#d64e40" d="M125.09303719488477,-99.75836829739735A160,160 0 0,1 125.09303719488477,-99.75836829739735L53.16454080782603,-42.397306526393876A68,68 0 0,0 53.16454080782603,-42.397306526393876Z">
</path>
<path fill="#f78837" d="M125.09303719488477,-99.75836829739735A160,160 0 0,1 125.09303719488477,-99.75836829739735L53.16454080782603,-42.397306526393876A68,68 0 0,0 53.16454080782603,-42.397306526393876Z">
</path>
<path fill="#ecc837" d="M125.09303719488477,-99.75836829739735A160,160 0 0,1 125.09303719488477,-99.75836829739735L53.16454080782603,-42.397306526393876A68,68 0 0,0 53.16454080782603,-42.397306526393876Z">
</path>
<path fill="#8bd38b" d="M125.09303719488477,-99.75836829739735A160,160 0 1,1 -2.9391523179536473e-14,-160L-1.2491397351303002e-14,-68A68,68 0 1,0 53.16454080782603,-42.397306526393876Z">
</path>
<path fill="#43b373" d="M-2.9391523179536473e-14,-160A160,160 0 0,1 -2.9391523179536473e-14,-160L-1.2491397351303002e-14,-68A68,68 0 0,0 -1.2491397351303002e-14,-68Z">
</path>
</g>
</svg>
</div>
But when I try to save as a PNG in console, I get the TypeError. The command I type in the Chrome console is saveSvgAsPng(document.getElementById('fish'), 'filename.png')
Any ideas?
Thanks!
The script is nicely pulling in all of my svg styles when generating the png, except for fonts embedded using @font-face { ... } . It looks like the saveSvgAsPng script should handle embedded fonts within the styles() function on lines 73-74, so I'm wondering if there's something I'm missing here. I'm using a truetype font in my @font-face declaration. Are there any known issues when using embedded fonts?
I am working with a specific case where the SVG has width="100%" and height="100%". With the current implementation my output PNG has width of 100px and height of 100px.
I managed to fix this by modifying the code to use dimensions from getBoundingClientRect()
Is it possible to save the png images with a specified background colour? For example, defaulting this to white instead of transparent?
EDIT: I have forked the repo and added this functionality with the existing options
hash that can be passed into the saveSvgAsPng()
function. I have created a pull request for this change.
When I try to copy a simple SVG, everything is fine excepting the TEXT tag that is rendered in Chrome (v34 for Windows 7) with a very small font size.
Rendering is OK with Firefox and with Internet Explorer.
Hi exupero,
on Chrome your script is doing well, but I observed some issuses with other browsers:
On Firefox 30.0 small fonts turn into normal sized fonts. On my test page you can see this at the elevation label. Please check:
https://dl.dropboxusercontent.com/u/17823304/Climograph/Climograph_test.html
On Opera 12.17 and Internet Explorer 11 the lownload is not working at all.
Hope to not report known issues.
This is a great initiative. I tried to use it on a Leaflet map. However, it seems that there are several SVG layer elements. So I only get certain parts of a map. It would be great to have a more general saveDivAsPng that could include SVG (or not).
Correction: There is only a single SVG layer in my LeafletJS map, but the labels are DIVs and as such do not show up in the png image. Again the solution would be to draw DIV layers including SVG. But I'm not sure this is possible.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.