javascript - 无法使用canvg将svg转换为png

标签 javascript jquery canvas svg

我正在尝试使用canvg将svg转换为canvas,并将转换后的canvas保存为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();
}

上面的代码工作正常,并将所有 svgs 下载为 png 图像,但正如您所看到的,使用几乎相同的语句调用 saveImage() 方法 8 次是有必要的。所以我尝试使用循环来做到这一点 -

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

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

最佳答案

问题

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

如果不是,结果可能会有些随机,具体取决于各种因素,例如缓存、canvg 内部 svg 到 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 标记的同一轮中调用单击。您可以向 a 元素添加一个单击事件处理程序,然后从那里调用回调,但这会导致方法有些过于复杂。

或者您可以使用 ID 方法(只需记住使用唯一的 ID)并迭代它们并执行 click() 调用(来自 didCallback)。

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

关于javascript - 无法使用canvg将svg转换为png,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29539271/

相关文章:

javascript - 在我显示一个 id 元素后页面突然跳到顶部

javascript - 如果选中其他具有相同值的复选框,则检查复选框 jquery

html - 在没有 Canvas 元素的情况下在 HTML 中裁剪 DIV

javascript - 为什么JS中函数前面要加 '('?

javascript - 使用 JavaScript 更新 gridview 的下拉列表?

javascript - jQuery:将格式化文本插入文本区域

javascript - 如何将 json 字符串传递给 webmethod c# ASP.NET

javascript - 触摸事件 "touchstart"在 Mobile Safari 上返回错误位置。解决方法?

css - <canvas> 的纵横比行为 - 内部尺寸和元素大小

javascript - 获取滑动的速度值?