将嵌入式SVG就地转换为PNG

jjk*_*ker 32 html svg

我在使用SVG图像(从MathML转换)时从Docbook源生成HTML.这适用于某些可以解释SVG的浏览器,但对其他浏览器则无效.

我真正想要的是添加一个后处理步骤,将SVG"就地"(在HTML中)转换为PNG.

所以像这样:

<body>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
        <circle cx="50" cy="50" r="30" />
    </svg>
</body>
Run Code Online (Sandbox Code Playgroud)

将无缝转换为:

<body>
    <img src="img0001.png" />
</body>
Run Code Online (Sandbox Code Playgroud)

而且我会得到一个转换后的PNG.

有什么东西可以做到这一点吗?

Phr*_*ogz 46

演示:http://phrogz.net/SVG/svg_to_png.xhtml

  1. 创建一个img并将其src设置为SVG.
  2. 创建HTML5画布并用于drawImage()将该图像绘制到画布上.
  3. toDataURL()在画布上使用以获得base64编码的PNG.
  4. 创建一个img并将其src设置为该数据URL.
var mySVG    = document.querySelector('…'),      // Inline SVG element
    tgtImage = document.querySelector('…'),      // Where to draw the result
    can      = document.createElement('canvas'), // Not shown on page
    ctx      = can.getContext('2d'),
    loader   = new Image;                        // Not shown on page

loader.width  = can.width  = tgtImage.width;
loader.height = can.height = tgtImage.height;
loader.onload = function(){
  ctx.drawImage( loader, 0, 0, loader.width, loader.height );
  tgtImage.src = can.toDataURL();
};
var svgAsXML = (new XMLSerializer).serializeToString( mySVG );
loader.src = 'data:image/svg+xml,' + encodeURIComponent( svgAsXML );
Run Code Online (Sandbox Code Playgroud)

但是,这个答案(以及所有客户端唯一的解决方案)都要求浏览器支持SVG,这可能会使其无法满足您的特定需求.

编辑:此答案假定SVG作为单独的URL提供.由于此问题中描述的问题,我无法使上述内容与嵌入在执行工作的同一文档中的SVG文档一起使用.

编辑2:Chrome和Firefox的改进克服了其他问题中描述的问题.仍然有一个限制,即<svg>元素必须具有width="…" height="…"Firefox的属性才能将其绘制到画布.每当你向它绘制任何SVG时(无论来源如何), Safari目前都会污染整个画布,但这应该很快就会改变.

  • 这很棒.Mozilla在这里写了一篇关于如何完全做到这一点的好白皮书:https://developer.mozilla.org/en-US/docs/HTML/Canvas/Drawing_DOM_objects_into_a_canvas.没有你建议的行动方案就找不到它. (3认同)
  • 截至2015年11月29日,Safari STILL AS YET不允许通过`toDataURL()`将SVG转换为PNG.有效地渲染到目前为止我发现的任何解决方案只有部分:(来吧Apple. (2认同)

小智 5

我在上周末遇到了这个问题,最终编写了一个简单的库来完成 Phrogz 所描述的或多或少的工作。它还硬编码目标 SVG 的样式以避免渲染问题。希望下一个寻找方法的人可以简单地使用我的代码并继续进行更有趣的挑战!

PS 我只在 Chrome 中测试过这个。

// Takes an SVG element as target
function svg_to_png_data(target) {
  var ctx, mycanvas, svg_data, img, child;

  // Flatten CSS styles into the SVG
  for (i = 0; i < target.childNodes.length; i++) {
    child = target.childNodes[i];
    var cssStyle = window.getComputedStyle(child);
    if(cssStyle){
       child.style.cssText = cssStyle.cssText;
    }
  }

  // Construct an SVG image
  svg_data = '<svg xmlns="http://www.w3.org/2000/svg" width="' + target.offsetWidth +
             '" height="' + target.offsetHeight + '">' + target.innerHTML + '</svg>';
  img = new Image();
  img.src = "data:image/svg+xml," + encodeURIComponent(svg_data);

  // Draw the SVG image to a canvas
  mycanvas = document.createElement('canvas');
  mycanvas.width = target.offsetWidth;
  mycanvas.height = target.offsetHeight;
  ctx = mycanvas.getContext("2d");
  ctx.drawImage(img, 0, 0);

  // Return the canvas's data
  return mycanvas.toDataURL("image/png");
}

// Takes an SVG element as target
function svg_to_png_replace(target) {
  var data, img;
  data = svg_to_png_data(target);
  img = new Image();
  img.src = data;
  target.parentNode.replaceChild(img, target);
}
Run Code Online (Sandbox Code Playgroud)


Jos*_*rce 3

FOP 和蜡染

http://xmlgraphics.apache.org/fop/

http://xmlgraphics.apache.org/batik/

来自 Apache 的 FOP 结合了同样来自 Apache 的 Batik。Batik 有一个 SVG 渲染工具,可以生成 PNG。FOP也是一个文档生成工具。