3

我的高级目标是将<div>包含一些内联 svg 图像的元素转换为 png 文件。所有操作都必须使用 JavaScript 在客户端浏览器中执行。我试过了:

  1. 使用canvg库并按照这篇文章中的步骤操作:https ://github.com/niklasvh/html2canvas/issues/95#issuecomment-34439223

    原始svg:

    原始 svg

    结果:

    画布结果

  2. 将css样式展平到<svg>标签中,然后调用canvg,按照这篇文章的步骤:将嵌入式SVG就地转换为PNG

    结果:空白图像。

  3. 将 css 样式展平到<svg>标签中并手动将 svg 绘制到画布上,按照这篇文章中的步骤操作: 如何将带有 css 样式的内联 SVG 从浏览器保存/导出到图像文件

    结果:空白图像。

  4. 使用以下代码将 css 样式展平为内联样式表:http: //spin.atomicobject.com/2014/01/21/convert-svg-to-png/

    结果:空白图像。

  5. 使用svg crowbar手动将<div>元素下载为 .svg 文件。

    结果:

    在此处输入图像描述

    然后,当我将原始 svg 的计算 css 与下载的 svg 进行比较时,我发现下载的 svg 具有正确的 svg xml,但内联样式表不正确 ( <style type="text/css">) 例如图最右侧的数字 200、300,它们在我的外部 css中绘制<text x="214" dy=".32em" y="0" style="text-anchor: start;">200</text>,我有:

    .scatterChart .axisGraphicsContext 文本 { 字体大小:8px; 填写:#777;}

    但是,下载的 svg 的内联样式表中没有 font-size 和 fill 属性。

4

1 回答 1

2

我一直在寻找一种解决方案,使用通过 Rickshaw(基于 D3)创建的 CSS 导出 PNG。我找到的唯一解决方案是:

  • 将 DIV 与 SVG 区别对待,并单独对待它们
  • 将带有 html2canvas 的 DIV(和其他非 SVG 内容)转换为画布
  • 使 CSS 内联到 SVG;@thirdcreed 已在以下位置发布了 JavaScript 代码和 D3 选择器:JSDOM 中的 Rickshaw CSS/Axes - 根据需要将其适应您的自定义 CSS。
  • 使用以下代码将 SVG 转换为画布

    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);
    }
    
  • 将您拥有的不同画布合并为一个
  • 使用以下代码转换为图像:

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

请注意,Internet Explorer 的每个浏览器都要求 SVG 具有 xmlns 属性。

于 2015-01-19T12:48:58.603 回答