简体   繁体   中英

Large svg to png in fixed resolution

I am using canvg lib to convert svg to png but some how when my svg size is more than 10000 it fails to draw it on canvas and data-URL get only "data:;" empty

here is my code that I am using

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);
         }
        }
    });
}

About This function .. there d3.js code which create diagram. and one save and download button is there save will get data URL to png and save it on server while download will download image instantly.. same function work for both with arguments .

Issue comes with "renderCallback " while svg is large that data URL comes empty I tried with timeout also but it's not get me result and timer keep running

I made my tests, finally, and actually, it seems to work well until approximately a size of 23500 x 23500 px in Firefox.

But only if you change the

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

with

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

Also, canvg seems to set itself the size of the rendering canvas, so your

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

is useless, probably as is the part where you set _canvasWidth and _canvasHeight .

__Be carefull with this snippet, there will be lags__

 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__**--> 

here is what i try to fix this for temp

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);
        }
    }
  });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM