4

I'm interested in creating a PNG from SVG. I followed the code given in:

https://developer.mozilla.org/en-US/docs/HTML/Canvas/Drawing_DOM_objects_into_a_canvas

But the image does not come out right due to styling from CSS. I made a local CSS file and do an import into the SVG, as described in:

How to apply a style to an embedded SVG?

But it does not appear to be using the style sheet. Any ideas why I would have this error?

Thanks.

Community
  • 1
  • 1
Justin
  • 287
  • 3
  • 11
  • 1
    why not do it in photoshop? – dezman Mar 05 '13 at 17:53
  • or inkscape for a free open source software. – Jake Mar 05 '13 at 18:26
  • I have an SVG that can't be opened properly in Inkscape (all of the gradients are missing), so I can sympathize with the OP. Some more details about how it works/doesn't work (colors/size/etc. are wrong) would be helpful here. – cimmanon Mar 05 '13 at 19:41
  • I know I can find a way to save the SVG out, load it into Inkscape, edit all the errors between Chrome and Inkscape renderings, and save to PNG. I'm using SVG because I'm created graphs via D3, so I'm using a web service. I'd like to save pretty pics (not screen captures) of the static SVG created. The CSS style are not being applied, and I'm using the method in the second link. – Justin Mar 06 '13 at 02:33
  • Any luck on this? I'm looking for a solution to this as well. – 111 Sep 17 '14 at 14:58
  • @glyph I kind of gave up on this and didn't pursue it much. Have you looked at http://nytimes.github.io/svg-crowbar/? I've played with it, appears to work. – Justin Sep 18 '14 at 15:18
  • Haven't seen that one. Chrome only is not going to work for my application but I'm trying this out: http://spin.atomicobject.com/2014/01/21/convert-svg-to-png/ - thanks though. – 111 Sep 18 '14 at 17:52

3 Answers3

0

Have a look at PhantomJS - You need to install it then either write your own script or run something along these lines:

phantomjs rasterize.js http://ariya.github.com/svg/tiger.svg tiger.png

You can also save to PDF, set Zoom setting, etc.

Izhaki
  • 23,372
  • 9
  • 69
  • 107
0

You could use html2canvas to generate a canvas from any dom element (including svg elements).

However, style definitions for svg elements defined in stylesheets are not applied to the generated canvas. This can be patched by adding style definitions to the svg elements before calling html2canvas.

Inspired on this article, I've created this:

function generateStyleDefs(svgDomElement) {
  var styleDefs = "";
  var sheets = document.styleSheets;
  for (var i = 0; i < sheets.length; i++) {
    var rules = sheets[i].cssRules;
    for (var j = 0; j < rules.length; j++) {
      var rule = rules[j];
      if (rule.style) {
        var selectorText = rule.selectorText;
        var elems = svgDomElement.querySelectorAll(selectorText);

        if (elems.length) {
          styleDefs += selectorText + " { " + rule.style.cssText + " }\n";
        }
      }
    }
  }

  var s = document.createElement('style');
  s.setAttribute('type', 'text/css');
  s.innerHTML = "<![CDATA[\n" + styleDefs + "\n]]>";
  //somehow cdata section doesn't always work; you could use this instead:
  //s.innerHTML = styleDefs;

  var defs = document.createElement('defs');
  defs.appendChild(s);
  svgDomElement.insertBefore(defs, svgDomElement.firstChild);
}

// generate style definitions on the svg element(s)
generateStyleDefs(document.getElementById('svgElementId'));

// after generating the style defintions, call html2canvas
html2canvas(document.getElementById('idOfElement')).then(function(canvas) {
  document.body.appendChild(canvas);
});
R. Oosterholt
  • 7,720
  • 2
  • 53
  • 77
-1

The example at

"How to apply a style to an embedded SVG?" as you mentioned should work. You need to define youObjectElement in this line of code when you test it.

var svgDoc = yourObjectElement.contentDocument;

try again.

Bew Promtong
  • 61
  • 1
  • 2
  • 7
  • 1
    I can generate the image, it's the CSS that's not being properly applied. I'm rendering from SVG created by D3.js. – Justin Mar 06 '13 at 02:34
  • I normally just use it and style it for small display. Did you try to follow this article? http://stackoverflow.com/questions/11978995/how-to-change-color-of-svg-image-using-css-jquery-svg-image-replacement/ . It might actually a good way to do it. – Bew Promtong Mar 06 '13 at 18:51
  • I basically did all the right things, I believe there is just limitations between CSS and SVG. Some things look good. Also, do invisible objects (like rectangles for zooming) hide objects underneath? – Justin Mar 08 '13 at 04:46
  • Are you trying to do an interactive SVG? I am not sure what you mean. – Bew Promtong Mar 10 '13 at 20:19