【问题标题】:Large svg to png in fixed resolution固定分辨率的大svg到png
【发布时间】:2015-05-18 19:56:06
【问题描述】:

我正在使用 canvg lib 将 svg 转换为 png,但是当我的 svg 大小超过 10000 时,它无法在画布上绘制它并且 data-URL 仅获取“data:;”空的

这是我正在使用的代码

function getDiagramImage(isTrue,_callback){
var html = d3.select("svg")
    //.attr("version", 1.1)
    //.attr("xmlns", "http://www.w3.org/2000/svg")
    .attr({
        'xmlns': 'http://www.w3.org/2000/svg',
        'xmlns:xmlns:xlink': 'http://www.w3.org/1999/xlink',
        version: '1.1'
    }) 
    .node().parentNode.innerHTML;


   d3.select('#hiddenCanvas').attr('width',_canvasWidth).attr('height',(parseFloat(_canvasHeight) + 300) );
   var canvas = document.getElementById('hiddenCanvas');
   var context = canvas.getContext("2d");

   canvg(document.getElementById('hiddenCanvas'), html, {
     renderCallback: function() {
         var dataURL = canvas.toDataURL();
         if(!isTrue){
           var pngimg = '<img src="'+dataURL+'">'; 
           d3.select("#pngdataurl").html(pngimg);

           var a = document.createElement("a");
           a.download = "export_"+Date.now()+".png";
           a.href = dataURL; 
           document.body.appendChild(a);
           a.click();  
         }
         if(_callback){
             _callback(dataURL);
         }
        }
    });
}

关于此功能.. 有创建图表的 d3.js 代码。并且有一个保存和下载按钮,保存将获取 png 的数据 URL 并将其保存在服务器上,同时下载将立即下载图像。相同的功能适用于两个参数。

问题来自“renderCallback”,而 svg 很大,数据 URL 为空我也尝试超时,但它没有得到结果,计时器继续运行

【问题讨论】:

  • 好的,它描述了问题,但有解决方案吗?
  • 好吧,如果这是问题所在,解决方案是将您的 svg 解析为多个堆叠的画布,如接受答案的 cmets 中所建议的那样。不知道canvg有没有支持这个
  • 我检查了高度是否超过 10000 我将其设置为 scaleHeight 10000 但 canvg 设置画布高度 34000 而不是 10000

标签: javascript canvas svg d3.js html5-canvas


【解决方案1】:

最后,我进行了测试,实际上,它似乎运行良好,直到 Firefox 中的大小约为 23500 x 23500 px

但前提是你改变了

d3.select("svg")
.attr(foo:bar)
.node().parentNode.innerHTML

d3.select("svg")
.attr(foo:bar)
.node().outerHTML();

此外,canvg 似乎会自行设置渲染画布的大小,因此您的

d3.select('#hiddenCanvas').attr('width',_canvasWidth).attr('height',(parseFloat(_canvasHeight) + 300) );

没用,可能是你设置_canvasWidth_canvasHeight的部分。

__小心这个sn-p,会有滞后__

function getDiagramImage(isTrue,_callback){
var html = d3.select("svg")
    .attr({
        'xmlns': 'http://www.w3.org/2000/svg',
        'xmlns:xmlns:xlink': 'http://www.w3.org/1999/xlink',
        version: '1.1'
    }) 
    .node().outerHTML;
   var canvas = document.getElementById('hiddenCanvas');
   var context = canvas.getContext("2d");

   canvg(canvas, html, {renderCallback: function(){
		 var dataURL = canvas.toDataURL();
         if(!isTrue){
           var pngimg = '<img src="'+dataURL+'">'; 
           d3.select("#pngdataurl").html(pngimg);

           var a = document.createElement("a");
           a.download = "export_"+Date.now()+".png";
           a.href = dataURL; 
           document.body.appendChild(a);
          // a.click();  
         }
         if(_callback){
             _callback(dataURL);
         }
   }});
   }
getDiagramImage();
svg{border:3px solid green;}
canvas{border:3px solid blue;}
img{border:3px solid red;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.13.0/exporting/canvg.js"></script>
<svg id="svg" xmlns="http://www.w3.org/2000/svg"
		 xmlns:xlink="http://www.w3.org/1999/xlink" width="15000" height="15000" viewBox="-0.5,0,500.5,500.5"> 
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="-0.5,118 382,500.5 441,500.5 -0.5,59 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="-0.5,295 205,500.5 264,500.5 -0.5,236 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="-0.5,59 441,500.5 500,500.5 499.8,500.2 -0.5,0 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="-0.5,354 146,500.5 205,500.5 -0.5,295 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="-0.5,500.5 28,500.5 -0.5,472 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="-0.5,472 28,500.5 87,500.5 -0.5,413 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="-0.5,413 87,500.5 146,500.5 -0.5,354 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="-0.5,236 264,500.5 323,500.5 -0.5,177 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="499.5,0.5 448,0.5 499.5,52 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="499.5,52 448,0.5 392,0.5 499.5,108 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="0,0.5 499.5,500 499.5,444 56,0.5 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="392,0.5 336,0.5 499.5,164 499.5,108 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="280,0.5 499.5,220 499.5,164 336,0.5 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="56,0.5 499.5,444 499.5,388 112,0.5 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="112,0.5 499.5,388 499.5,332 168,0.5 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="168,0.5 499.5,332 499.5,276 224,0.5 	"/>
		<polygon fill="none" stroke="#000000" stroke-miterlimit="10" points="224,0.5 499.5,276 499.5,220 280,0.5 	"/>
	</svg>
<canvas id="hiddenCanvas"></canvas>
<div id="pngdataurl"></div>


<!--**__Be carefull with this snippet, there will be lags__**-->

【讨论】:

  • 是的,你可以在给定 svg 后自行设置画布的大小
  • 但是现在我做了这个 var _imageHeight = parseFloat(_canvasHeight); var _imageWidth = parseFloat(_canvasWidth);如果(_imageHeight > 10000){ _imageHeight = 9700; } if(_imageWidth > 7000){ _imageWidth = 7000;对于canvg canvg('hiddenCanvas', html, { ignoreMouse:true, ignoreAnimation:true, ignoreDimensions:true, scaleWidth:_imageWidth, scaleHeight:_imageHeight, renderCallback: function() {
【解决方案2】:

这是我尝试解决的临时问题

function getDiagramImage(isTrue,_callback){

var html = d3.select("#nodePane svg#nodeEditor")
    .attr({
        'xmlns': 'http://www.w3.org/2000/svg',
        'xmlns:xmlns:xlink': 'http://www.w3.org/1999/xlink',
        version: '1.1'
    }) 
    .node().parentNode.innerHTML;

var _imageHeight = parseFloat(_canvasHeight);
var _imageWidth = parseFloat(_canvasWidth);

if(_imageHeight > 10000){
     _imageHeight = 9700;
}

if(_imageWidth > 7000){
    _imageWidth = 7000;
}

d3.select('#hiddenCanvas').attr('width',_imageWidth+"px").attr('height',( _imageHeight + 300+"px" ) );
 var canvas = document.getElementById('hiddenCanvas');
 var context = canvas.getContext("2d");

 canvg('hiddenCanvas', html, {
      ignoreMouse:true,
      ignoreAnimation:true,
      ignoreDimensions:true,
      scaleWidth:_imageWidth,
      scaleHeight:_imageHeight,
      renderCallback: function() {
        var dataURL = canvas.toDataURL();
        if(!isTrue){
          var pngimg = '<img src="'+dataURL+'">'; 
          d3.select("#pngdataurl").html(pngimg);

          var a = document.createElement("a");
          a.download = "export_"+Date.now()+".png";
          a.href = dataURL; 
          document.body.appendChild(a);
          a.click();  
        }
        if(_callback){
            _callback(dataURL);
        }
    }
  });
}

【讨论】:

  • ignoreDimensions 不会将画布调整为 svg 的大小
  • 虽然我必须在我的网络上显示图像,所以我也必须注意尺寸...由于尺寸限制,这样最大 4-5 mb 的图像将在那里
猜你喜欢
  • 2017-10-02
  • 2013-02-06
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 2016-04-02
  • 2015-06-20
  • 2013-12-22
  • 1970-01-01
相关资源
最近更新 更多