带有嵌入式样式表的 SVG 到 PNG

Posted

技术标签:

【中文标题】带有嵌入式样式表的 SVG 到 PNG【英文标题】:SVG to PNG with Embedded Style Sheet 【发布时间】:2013-02-20 06:11:48 【问题描述】:

我对从 SVG 创建 PNG 感兴趣。我按照中给出的代码:

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

但由于 CSS 的样式,图像无法正确显示。我制作了一个本地 CSS 文件并导入到 SVG,如下所述:

How to apply a style to an embedded SVG?

但它似乎没有使用样式表。任何想法为什么我会出现这个错误?

谢谢。

【问题讨论】:

为什么不在photoshop中做呢? 或 inkscape 是一款免费的开源软件。 我有一个 SVG 无法在 Inkscape 中正确打开(所有渐变都丢失了),所以我可以同情 OP。有关它如何工作/不起作用(颜色/尺寸/等错误)的更多详细信息在这里会有所帮助。 我知道我可以找到一种方法来保存 SVG,将其加载到 Inkscape 中,编辑 Chrome 和 Inkscape 渲染之间的所有错误,然后保存为 PNG。我使用 SVG 是因为我是通过 D3 创建图形的,所以我使用的是 Web 服务。我想保存创建的静态 SVG 的漂亮图片(不是屏幕截图)。没有应用 CSS 样式,我在第二个链接中使用了 方法。 运气好吗?我也在寻找解决方案。 【参考方案1】:

您可以使用html2canvas 从任何 dom 元素(包括 svg 元素)生成画布。

但是,样式表中定义的 svg 元素的样式定义不会应用于生成的画布。这可以通过在调用 html2canvas 之前向 svg 元素添加样式定义来修补。

受this article 的启发,我创建了这个:

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);
);

【讨论】:

【参考方案2】:

查看PhantomJS - 您需要安装它,然后编写您自己的脚本或按照以下方式运行:

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

您还可以保存为PDF,设置缩放设置等。

【讨论】:

【参考方案3】:

例子在

“如何将样式应用于嵌入式 SVG?”正如你提到的应该工作。测试时需要在这行代码中定义youObjectElement。

var svgDoc = yourObjectElement.contentDocument;

再试一次。

【讨论】:

我可以生成图像,但没有正确应用 CSS。我正在从 D3.js 创建的 SVG 进行渲染。 我通常只是使用它并将其设置为小型显示。您是否尝试关注这篇文章? ***.com/questions/11978995/… 。这实际上可能是一个很好的方法。 我基本上做了所有正确的事情,我相信 CSS 和 SVG 之间只是存在限制。有些东西看起来不错。另外,不可见的对象(例如用于缩放的矩形)是否将对象隐藏在下面? 您是否正在尝试制作交互式 SVG?我不确定你的意思。

以上是关于带有嵌入式样式表的 SVG 到 PNG的主要内容,如果未能解决你的问题,请参考以下文章

Ghostscript - EPS(带有透明背景的嵌入式 TIFF)到 PNG 转换

在使用canvas api在浏览器中将svg转换为png时,svg中的嵌入图像在Safari中随机空白

将图像放在另一个 png/svg 文件中

在 matplotlib 图中绘制 SVG(嵌入在 wxPython 中)

使用带有嵌入式 PyPy 的外部“Python”样式 cffi 回调

将svg转换为png时如何包含CSS样式