简体   繁体   中英

Styling errors when converting inline SVG to png

My high level goal is to convert a <div> element containing a few inline svg images to a png file. All operations must be performed within the client browser using JavaScript. I have tried:

  1. using canvg library and following the steps from this post: https://github.com/niklasvh/html2canvas/issues/95#issuecomment-34439223

    original svg:

    原svg

    result:

    canvg结果

  2. flattening the css styles into the <svg> tag and then calling canvg, following the steps from this post: Convert embedded SVG to PNG in-place

    result: a blank image.

  3. flattening the css styles into the <svg> tag and manually drawing the svg onto a canvas, following the steps from this post: how to save/ export inline SVG styled with css from browser to image file

    result: a blank image.

  4. flattening the css styles into an inline style sheet using this code: http://spin.atomicobject.com/2014/01/21/convert-svg-to-png/

    result: a blank image.

  5. using svg crowbar to manually download the <div> element as an .svg file.

    result:

    在此输入图像描述

    then when I compared the computed css of the original svg against the downloaded svg, I found that the downloaded svg had the correct svg xml but an incorrect inline stylesheet ( <style type="text/css"> ) For example the numbers 200, 300 on the far right of the graph, they were drawn with <text x="214" dy=".32em" y="0" style="text-anchor: start;">200</text> and in my external css, I have:

    .scatterChart .axisGraphicsContext text { font-size: 8px; fill: #777; }

    However, the font-size and fill properties were absent from the inline stylesheet of the downloaded svg.

I've been searching myself for a solution to export PNG with CSS created through Rickshaw (based on D3). The sole solution I found was to:

  • treat the DIVs different from the SVGs, and treat them all individually
  • convert the DIVs (and other non-SVG content) with html2canvas to canvas
  • make the CSS inline to the SVG; @thirdcreed has posted the JavaScript code and D3 selectors for that at: Rickshaw CSS/Axes in JSDOM - adapt that to your custom CSS as needed.
  • convert the SVGs into canvas with code such as

     var imgsrc = 'data:image/svg+xml;base64,'+ btoa(html2); var img = '<img src="'+imgsrc+'">'; var canvas = document.querySelector("canvas"), context = canvas.getContext("2d"); var image = new Image; image.src = imgsrc; image.onload = function() { context.drawImage(image, 0, 0); } 
  • merge the different canvases you have into one
  • convert into image with code such as:

     var canvasdata = canvas.toDataURL("image/png"); var pngimg = '<img src="'+canvasdata+'">'; d3.select("#pngdataurl").html(pngimg); // contains selector from D3, adjust if you don't use D3 var a = document.getElementById("some_anchor"); // Fix for Firefox: supply an anchor-tag here that is 'display:none' in your document, otherwise download won't work a.download = "sample.png"; a.href = canvasdata; a.click(); 

Note that every browser expect for Internet Explorer requires the SVGs to have the xmlns attribute.

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