【问题标题】:Unable to covert svg to png using canvg无法使用canvg将svg转换为png
【发布时间】:2015-04-09 13:03:06
【问题描述】:

我正在尝试使用 canvg 将 svg 转换为画布,并将转换后的画布另存为 png 在我的计算机上。 这是我正在使用的代码 -

function downloadImage()
{
    saveImage('chart1');
    saveImage('chart2');
    saveImage('chart3');
    saveImage('chart4');
    saveImage('chart5');
    saveImage('chart6');
    saveImage('chart7');
    saveImage('chart8');
}

function saveImage(chartId)
{
    var $container = $('#'+chartId),
    content = $container.html().trim();
    var canvas1 = document.createElement('canvas');
    var w=1366,h=768;
    canvas1.id     = "canvas1";
    canvas1.width  = w;
    canvas1.height = h;
    document.getElementById('pngcon').appendChild(canvas1);

    var canvas = document.getElementById('canvas1');

    canvg(canvas, content);
    var theImage = canvas.toDataURL('image/png');
    var a = document.createElement("a");
    a.id="imagepng"
    a.download = fileName+chartId+".png";
    a.href = theImage;
    document.body.appendChild(a);
    document.getElementById("imagepng").click();
    $("#pngcon").html('');

    $("#imagepng").remove();
}

上面的代码工作正常,并将所有 svg 下载为 png 图像,但正如您所见,使用几乎相同的语句调用 saveImage() 方法 8 次是有道理的。所以我尝试使用循环来执行此操作 -

function downloadImage()
   {
       for(i=1;i<=8;i++)
       {
           saveImage('chart'+i);
       }
   }

但这次错过了其中一个 svg。我对这里发生的事情一无所知。请帮忙...

【问题讨论】:

    标签: javascript jquery canvas svg


    【解决方案1】:

    问题

    canvg 方法是异步的,这意味着您需要使用回调方法才能使其正常工作。

    如果不是这样,结果可能会有些随机,具体取决于各种因素,例如缓存、canvg 内部对 svg-to-canvas 的处理、浏览器处理内部图像 URL 的速度等。

    解决方案:处理异步性

    首先你需要修改saveImage()方法来进行回调:

    function saveImage(chartId, callback) { ... }
    

    然后在其中使用canvg的回调:

    canvg(canvas, content, {renderCallback: function() {
        var theImage = canvas.toDataURL('image/png');
        var a = document.createElement("a");
        a.download = fileName+chartId+".png";
        a.href = theImage;
        document.body.appendChild(a);
        a.click();               // use the element directly instead of getting it from DOM
        $("#pngcon").html('');
        $("#imagepng").remove();
    
        callback();                                 // gets next image
    }});
    

    现在我们可以创建一个异步处理它的“循环”:

    function downloadImage(doneCallback) {
        var i = 0;                                  // accessible from within next()
        (function next() {
            if (++i < 9) {                          // increase counter, then check [1,8]
                saveImage('chart' + i, next);       // use this method as callback
            }
            else {
                if (doneCallback) doneCallback();   // when done, invoke main callback
            }
        })();                                       // self-invokes next()
    }
    

    您现在可以使用可选回调调用downloadImage

    downloadImage(function() {alert("done")})
    

    但是,您可能需要考虑是否在生成 a 标记的同一轮中调用点击。您可以将 click 事件处理程序添加到 a 元素,然后从那里调用回调,但这会导致方法过于复杂。

    或者您可以使用 ID 方法(只需记住使用唯一 ID)并对其进行迭代,然后执行 click() 调用(来自 doneCallback)。

    不过,这超出了这个问题的范围。

    【讨论】:

    • 非常感谢@Ken。按照你的建议做了...问题解决了! :)
    • @ValarMorghulis 很高兴听到。很高兴它解决了:)
    猜你喜欢
    • 2016-03-21
    • 1970-01-01
    • 2016-03-12
    • 2016-03-09
    • 2012-10-02
    • 2015-10-04
    • 2015-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多