如何将Base64编码的SVG图片转换为Base64编码的PNG图片?

4

我有一段代码可以将图表转换成SVG格式,但是我需要输出PNG格式的图片。 svgString2Image 是一个函数,它返回一个编码为base64的SVG字符串。我该如何实现呢?非常感谢。

function svgString2Image( svgString, width, height, format, callback ) {
  //console.log("svgString",svgString)
    format ? format : 'png';

    var imgsrc = 'data:image/svg+xml;base64,'+ btoa( unescape( encodeURIComponent( svgString ) ) ); // Convert SVG string to data URL
    var canvas = document.createElement("canvas");
    var context = canvas.getContext("2d");

    canvas.width = width;
    canvas.height = height;

    var image = new Image();
    image.onload = function() {
        context.clearRect ( 0, 0, width, height );
        context.drawImage(image, 0, 0, width, height);

        canvas.toBlob( function(blob) {
            var filesize = Math.round( blob.length/1024 ) + ' KB';
            if ( callback ) callback( blob, filesize );
        });

    };
    ///****************************
  document.getElementById('my_image').src=imgsrc;
    return image.src = imgsrc;

}

http://plnkr.co/edit/lPhmuYywPCdjQrnwhQcH?p=preview


1
使用回调函数。 - Bergi
@meager,链接的问题和答案如何解决当前问题的代码问题? - guest271314
format 从未被使用,但 canvas.toBlob 的默认格式是'image/png'。如果您想指定格式,请将 'image/' + format 添加为第二个参数到 canvas.toBlob - William Lohan
在哪里?怎么做到? - yavg
http://plnkr.co/edit/x4Db6spSxdEAQEqoeAi1?p=preview - William Lohan
显示剩余2条评论
2个回答

12

就像@guest271314和我在评论中所提到的那样,当需要base64字符串时,请使用canvas.toDataURL而不是canvas.toBlob。此外,image.onload是异步的,因此不可能“返回”base64 png字符串。您必须使用回调函数(或者如@guest271314所述的Promise)。

function svgString2Image(svgString, width, height, format, callback) {
    // set default for format parameter
    format = format ? format : 'png';
    // SVG data URL from SVG string
    var svgData = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgString)));
    // create canvas in memory(not in DOM)
    var canvas = document.createElement('canvas');
    // get canvas context for drawing on canvas
    var context = canvas.getContext('2d');
    // set canvas size
    canvas.width = width;
    canvas.height = height;
    // create image in memory(not in DOM)
    var image = new Image();
    // later when image loads run this
    image.onload = function () { // async (happens later)
        // clear canvas
        context.clearRect(0, 0, width, height);
        // draw image with SVG data to canvas
        context.drawImage(image, 0, 0, width, height);
        // snapshot canvas as png
        var pngData = canvas.toDataURL('image/' + format);
        // pass png data URL to callback
        callback(pngData);
    }; // end async
    // start loading SVG data into in memory image
    image.src = svgData;
}

// call svgString2Image function
svgString2Image(svgString, 800, 600, 'png', /* callback that gets png data URL passed to it */function (pngData) {
    // pngData is base64 png string
});

谢谢!我能否在不使用回调函数的情况下获取base64字符串,例如:var png=svgString2Image(svgString, 800, 600, 'png) - yavg
此外,image.onload 是异步的,因此不可能“返回”base64 png字符串。您必须使用回调函数(或者像 @guest271314 所述的 Promise)。 - William Lohan
好的,我想知道是否还有其他方法。非常感谢。 - yavg
据我所知,我只知道你现在这样做的方式,即将图像绘制到画布上,并在画布上调用toSomthing()函数(在本例中为toDataURL)。在将其绘制到画布之前,您必须等待原始数据(在本例中为SVG数据)中的图像加载,即image.onload函数。这使整个过程异步化。 - William Lohan

1
在最后一个参数中未传递任何函数给svgString2Image。将一个期望blobfilesize参数的函数传递给svgString2Image

你能帮我吗?我只需要将结果以base64 png格式返回为图像。 - yavg
“return”是什么意思?你编写了这个函数,那么“callback”的目的是什么?svgString2Image(svgString, 800, 600, 'png', function(blob, filesize) {//do stuff with blob and filesize}); - guest271314
这意味着将字符串 base64 转换为 png 格式。我对代码的这部分没有用途。我只是为了以防万一,以便将字符串生成为 png 格式。 - yavg
为什么在期望结果是数据URI时要使用canvas.toBlob()?虽然你可以使用Promise从函数调用中返回一个Promise对象,并使用.then()获取已完成的Promise的值,但无法在异步函数内部使用return - guest271314

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接