【问题标题】:Convert SVG to image in PNG将 SVG 转换为 PNG 格式的图像
【发布时间】:2017-05-11 11:06:35
【问题描述】:

我正在使用 html2canvas 和 canvg 插件将角度 nvd3 图表转换为 svg,但是当我将饼图转换为 png 时,我看起来与图表相同,但是当我转换折线图或面积图时,它的背景变为黑色,并且一些圆圈被淹没图片。 我的代码是

var svgElements = $("#container").find('svg');

            //replace all svgs with a temp canvas
            svgElements.each(function () {
                var canvas, xml;

                // canvg doesn't cope very well with em font sizes so find the calculated size in pixels and replace it in the element.
                $.each($(this).find('[style*=em]'), function (index, el) {
                    $(this).css('font-size', getStyle(el, 'font-size'));
                });

                canvas = document.createElement("canvas");
                canvas.className = "screenShotTempCanvas";
                //convert SVG into a XML string
                xml = (new XMLSerializer()).serializeToString(this);

                // Removing the name space as IE throws an error
                xml = xml.replace(/xmlns=\"http:\/\/www\.w3\.org\/2000\/svg\"/, '');

                //draw the SVG onto a canvas
                canvg(canvas, xml);
                $(canvas).insertAfter(this);
                //hide the SVG element
                ////this.className = "tempHide";
                $(this).attr('class', 'tempHide');
                $(this).hide();
            });


            html2canvas($("#container"), {
                onrendered: function (canvas) {
                    var a = document.createElement("a");
                    a.download = "Dashboard.png";
                    a.href = canvas.toDataURL("image/png");
                    a.click();
                    var imgData = canvas.toDataURL('image/png');

                    var doc = new jsPDF('p', 'mm','a4');
                    var width = doc.internal.pageSize.width;    
                    var height = doc.internal.pageSize.height;

                    doc.addImage(imgData, 'PNG',  0, 0, width, height);
                    doc.save('Dashboard.pdf');
                }
            });

            $("#container").find('.screenShotTempCanvas').remove();
            $("#container").find('.tempHide').show().removeClass('tempHide');

帮帮我。 提前致谢

【问题讨论】:

  • 您是否从 <style> 元素对您的 svg 节点应用了一些样式?如果是这样,您需要在调用 XMLSerializer 之前将其包含在您的 svg 节点中。
  • @Kaiido 没有应用样式。
  • 你能做一个 jsfiddle 让我们看看你的 svg 是如何呈现的吗?

标签: angularjs nvd3.js html2canvas angular-nvd3 canvg


【解决方案1】:

谈话很晚,但我只是想补充一下 Kaiido 描述的解决方案,简单地说,就是将样式直接嵌入到 SVG 文档中。

为了做到这一点,你操作 DOM 使 SVG 元素看起来像这样:

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" version="1.1">
   <defs>
     <style>
       .rectangleStyle{
           width:200px;
           height:100px;
           stroke:black;
           stroke-width: 6;
           fill: green;
       }       
     </style>
   </defs>
   <rect class="rectangleStyle"/>
</svg>

【讨论】:

  • 谢谢,这是对 Kaiido 回答的一个很好的赞美。
【解决方案2】:

您的 svg 元素由外部样式表 nv.d3.min.css 设置样式。

canvg 似乎无法访问外部样式表,因此您需要将其直接附加到您的 svg 节点中。

为此,如果您的样式表与脚本托管在同一域中,您可以执行以下操作:

var sheets = document.styleSheets;
var styleStr = '';
Array.prototype.forEach.call(sheets, function(sheet){
    try{ // we need a try-catch block for external stylesheets that could be there...
        styleStr += Array.prototype.reduce.call(sheet.cssRules, function(a, b){
            return a + b.cssText; // just concatenate all our cssRules' text
            }, "");
        }
    catch(e){console.log(e);}
});
// create our svg nodes that will hold all these rules
var defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
var style = document.createElementNS('http://www.w3.org/2000/svg', 'style');
style.innerHTML = styleStr;
defs.appendChild(style);
// now append it in your svg node
thesvg[0].insertBefore(defs, thesvg[0].firstElementChild);

所以现在你可以调用 XMLSerializer,canvg 会很高兴。
(请注意,这不仅是 canvg 的限制,同样适用于在画布上绘制 svg 的所有方式)。

Forked plunkr,我将 nv.d3.min.css 的内容复制到 same-origin style.css .

【讨论】:

  • @dkc007, han,这是一个 chrome 错误和一个角度错误的实现.. ng 使用了一些 hackish [ng\:something] 选择器,而他们应该使用 [ng|something]... Chrome 很高兴地接受了这个 hack渲染,但它仅在样式表规则中存储[ng:something],而这稍后是无效的并引发此错误...这是另一个快速修复它的分支,通过避免具有这些规则:plnkr.co/edit/ZgT2P4Tu0Z9x63QwPNFB?p=preview
  • 请检查这个插件我无法在下载的图像中看到任何图像plnkr.co/edit/UaI7rtfMLxxCKt5xy6s3?p=preview
  • @dkc007 我告诉过你我在工作,这意味着我有一份工作可以给我需要的钱,而且奇怪的是,我的老板(给我钱的那个人)更喜欢看到我在工作时间为他工作,而不是在互联网上为某个不知名的人工作。你必须等待。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-06
  • 1970-01-01
  • 2017-05-16
  • 1970-01-01
  • 2021-11-24
  • 2011-05-11
相关资源
最近更新 更多