1

I am trying to convert svg to png and I found that the converted image is not the same as svg. How can as assure consistency among both svg and png?

Code to covert svg to png

    jQuery('#imgDiv').css({display: 'block', 'padding-left': '25px', overflow: 'scroll'});
    jQuery('#resImg').css({display: 'block', 'padding-left': '25px'});
    var svg = jQuery('#map').html().replace(/>\s+/g, ">").replace(/\s+</g, "<");
    // strips off all spaces between tags

    canvg('cvs', svg, {
        ignoreMouse: true,
        ignoreAnimation: true
    });
    var canvas = document.getElementById('cvs');

    img = canvas.toDataURL("image/png", 1);
    var a = document.createElement('a');
    a.href = img;
    a.download = "image.png";
    var clickEvent = new MouseEvent("click", {
        "view": window,
        "bubbles": true,
        "cancelable": false
    });
    a.dispatchEvent(clickEvent)

Everything is file but when I see the downloaded image the height,width is different and labels and fonts is not visible.

Code to generate svg:

var width = 1260,
        height = 910;
var svg = d3.select("#map")
            .append("svg")
            .attr("width", width)
            .attr("height", height)
            .on("contextmenu", function (d, i) {
                d3.event.preventDefault();
                printMap();
            });

    svg.append("rect")
            .attr("x", 0)
            .attr("y", 0)
            .attr("width", width)
            .attr("height", height)
            .style("stroke", '#000000')
            .style("stroke-opacity", 1)
            .style("fill", "#FFF")
            .style("fill-opacity", 0)
            .style("stroke-width", 2);

var cluster = topojson.feature(data, data.objects.clustergeojson).features;
        var projection = d3.geo.mercator();
        s = 250;

        projection.scale(8500)
                .center([83, 29.5]);

        var path = d3.geo.path().projection(projection);

        var b = path.bounds(cluster),
                s = .95 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height),
                t = [(width - s * (b[1][0] + b[0][0])) / 2, (height - s * (b[1][1] + b[0][1])) / 2];

Actual SVG:

enter image description here

Converted PNG:

enter image description here

Here is sample jsFiddle.

var projection = d3.geo.mercator()
  .scale(5000)
  .center([83.96, 28.27]);

If I change scale from 5000 to 6000 the svg is larger but not the png. The fiddle output svg can be right clicked to export as png.

kinkajou
  • 3,664
  • 25
  • 75
  • 128
  • 1
    Ive not long used this myself. Not sure what your problem is but not sure if you know, CSS styling only works if it's inline. If you give something a class and set the styles for that class in the CSS it won't work, for example, width height font size etc. Saying that, I know this line will show up in the generated canvas : ''.style("fill", "#FFF")'' in D3 but I am not sure about this line : ''jQuery('#imgDiv').css({display: 'block', 'padding-left': '25px', overflow: 'scroll'});@@ as I didn't use JQuery, I may be wrong. If you could, make a simple fiddle of your problem and Ill have a look – thatOneGuy Mar 20 '16 at 19:24
  • @thisOneGuy I found that the problem is with d3 scale which makes svg larger but png export is small size. Here is fiddle https://jsfiddle.net/bnLoq1Lw/6/. You can try with var projection = d3.geo.mercator() .scale(5000) .center([83.96, 28.27]); from 5000->6000 and right click on svg. – kinkajou Mar 22 '16 at 10:35

1 Answers1

1

Here is the fiddle I have played around with : https://jsfiddle.net/thatoneguy/bnLoq1Lw/9/

I have adjusted yours so you dont have to scroll to see the whole svg. Also added:

  • instead of right clicking, just a left click event.

  • on click, save to file but also save to an output div so you can see the output on screen straight away.

  • added inline styling so the styling comes out on the generated output.

Inline styling :

.style('stroke','red')
.style('fill','green')

Now when you change the scale, it all seems to work fine ? Where as before I couldn't even see anything.

Have a look at the fiddle I have shown, let me know if it works okay for you

thatOneGuy
  • 9,977
  • 7
  • 48
  • 90
  • I am not able to find the change? Did you translate svg? – kinkajou Mar 22 '16 at 12:04
  • Sorry forgot to mention I did translate it just to get it to the center : .attr('transform', 'translate('+(-width/2)+',0)'); //centre of svg, line 31 of the fiddle. Did this solve your problem then ? – thatOneGuy Mar 22 '16 at 12:23
  • I am not able to find change. I tried changing heigh and lenght but image is still croped and quality is same. https://jsfiddle.net/bnLoq1Lw/11/ I am wondering what is the main issue. – kinkajou Mar 23 '16 at 01:43
  • What is the problem ? That the map won't fit on screen ? Then you adjust the scale (https://jsfiddle.net/reko91/bnLoq1Lw/12/), or width and height and get rid of the translate (https://jsfiddle.net/reko91/bnLoq1Lw/13/). What is it you want to happen ? – thatOneGuy Mar 23 '16 at 08:55
  • Did you check the output image? It is smaller than the one shown on browser. I want both of then to be same. – kinkajou Mar 23 '16 at 10:04
  • Yeah they look fine to me :/ – thatOneGuy Mar 23 '16 at 10:18
  • I am sorry that I could not explain it clearly I think this fiddle will make it clear : https://jsfiddle.net/bnLoq1Lw/14/ Can you try to export?\ – kinkajou Mar 23 '16 at 13:30
  • 1
    @kinkajou that works fine. If you go to your image location, right click the file and go to properties, you will see that the dimensions are the same as the SVG : 1500 x 650 – thatOneGuy Mar 23 '16 at 13:43
  • did you check those font? They are blur and are not visible. – kinkajou Mar 23 '16 at 13:45
  • zoom all the way in, let it focus, then zoom out. I think canvas doesn't produce a hd image, try this fiddle : https://jsfiddle.net/bnLoq1Lw/15/, i have just set the width and height, kind of less blurry. See this link should solve the problem : http://www.html5rocks.com/en/tutorials/canvas/hidpi/ – thatOneGuy Mar 23 '16 at 13:55
  • 1
    I have accepted the answer. I will try to look into hidpi ! – kinkajou Mar 23 '16 at 14:11