0

我正在使用以下函数将 SVG 转换为 PNG 并将其作为下载提供:

<svg id="chart">
    ...some contenthere
</svg>

function() {
        var svg = $("#chart")[0],
            bBox = $('#chart')[0].getBBox();

        var width = bBox.width*2,
            height = bBox.height*2;

        var canvas = $("canvas")[0],
            serializer = new XMLSerializer(),
            svgString = serializer.serializeToString(svg);

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

        canvg(canvas, svgString);

        var dataURL = canvas.toDataURL('image/png'),
            data = atob(dataURL.substring('data:image/png;base64,'.length));

        asArray = new Uint8Array(data.length);

        for (var i = 0; i < data.length; ++i) {
            asArray[i] = data.charCodeAt(i); 
            } 

        var blob = new Blob([asArray.buffer], {type: 'image/png'}); 
        saveAs(blob, 'climatechart.png'); 
}

尽管输出图像与浏览器中的 SVG 大小相同,但它实际上工作正常。如何为图像设置新尺寸?我还尝试直接从 svg 而不是 BBox 获取大小,但它是一样的。

4

4 回答 4

1

此解决方案基于远程格式化服务器而不是本地代码。它使用 XSL FO 服务器端直接将 SVG 渲染为位图,允许您设置分辨率以获得高质量输出。

文档:http ://www.cloudformatter.com/CSS2Pdf.APIDoc.Usage

示例:http: //jsfiddle.net/g75t4oyq/

来自 SVG 的 JPG 格式 @ 300dpi 在 div 中的代码实现:

click="return xepOnline.Formatter.Format('JSFiddle', {render:'newwin', mimeType:'image/jpg', resolution:'300', srctype:'svg'})";
jQuery('#buttons').append('<button onclick="'+ click +'">JPG @300dpi</button>');
于 2015-12-16T18:02:22.240 回答
0

如果 svg 元素根据其大小定义了 viewBox 属性,则可以通过 height 和 width 属性调整 SVG 文档的大小;例如

<svg width="500" height="200" viewBox="0 0 50 20" >

设置 viewBox 后,画布中 svg 的缩放将按照您的编码工作。

于 2015-12-16T13:47:27.230 回答
0

您可以轻松地调整画布的大小,因为您可以将其绘制画布。以下示例忽略了任何 SVG 渲染,根据您的问题可以正常工作,但它确实显示了如何使用另一个画布轻松调整画布的大小:

var myCanvas = document.createElement('canvas');
var myCtx    = myCanvas.getContext('2d');
    myCanvas.width = 200;
    myCanvas.height = 200;
    myCtx.arc(100, 100, 100, 0, Math.PI * 2, true);
    myCtx.fill();

var seCanvas = document.createElement('canvas');
var seCtx    = seCanvas.getContext('2d');
    seCanvas.width = 200;
    seCanvas.height = 200;
    seCtx.drawImage(myCanvas, 0, 0, 100, 100);

document.body.appendChild(myCanvas);
document.body.appendChild(seCanvas);

之后,您可以使用这个新画布继续该过程。

于 2015-12-16T13:50:48.220 回答
0

好的,感谢您的建议,我终于找到了一个完美的解决方案(根据 Cédric Hartlands 的提示)。该viewbox属性是我的代码中完全缺少的部分。viewbox定义如下:

viewbox = "x y width height"

因此,要放大其中的<svg>所有元素,有必要确保视图框的widthheight与元素的新宽度和高度完全匹配<svg>

//original version
<svg> width="100" height="100" viewbox="0 0 100 100" preserveAspectRatio="xMinYMin meet"</svg>

//scaled up version
<svg> width="200" height="200" viewbox="0 0 200 200" preserveAspectRatio="xMinYMin meet"</svg>

如果我将放大的图像转换svgcanvas,它会适合整个图像而不会失去任何质量(无论如何这是矢量图的最大好处)。不敢相信我花了这么长时间才得到它。

于 2015-12-17T10:21:55.077 回答