Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Html 将嵌入式SVG就地转换为PNG_Html_Svg - Fatal编程技术网

Html 将嵌入式SVG就地转换为PNG

Html 将嵌入式SVG就地转换为PNG,html,svg,Html,Svg,我从Docbook源代码生成HTML,同时对图像使用SVG(从MathML转换)。这对于一些能够解释SVG的浏览器来说效果很好,但对于其他浏览器来说却失败了 我真正想要的是添加一个后处理步骤,将SVG“就地”(在HTML中)转换为PNG 比如说: <body> <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <circle cx="50" cy="50" r="30" />

我从Docbook源代码生成HTML,同时对图像使用SVG(从MathML转换)。这对于一些能够解释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>

将无缝转换为以下内容:

<body>
    <img src="img0001.png" />
</body>

我会得到一个经过转换的PNG

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

FOP和蜡染


阿帕奇的FOP采用了同样来自阿帕奇的蜡染。Batik有一个SVG渲染工具,可以生成PNG。FOP也是一种文档生成工具。

如果您想纯粹在客户端进行此操作,则需要两个步骤:

  • 将SVG转换为画布(http://code.google.com/p/canvas-svg/ 或其他一些工具)
  • 将画布转换为PNG(http://www.nihilogic.dk/labs/canvas2image/ 或其他一些工具)
  • 这显然只适用于支持HTML5的浏览器。

    Demo:
  • 创建一个
    img
    ,并将其src设置为SVG
  • 创建HTML5画布,并使用
    drawImage()
    将该图像绘制到画布上
  • 在画布上使用
    toDataURL()
    ,以获取base64编码的PNG
  • 创建一个img并将其src设置为该数据URL
  • var mySVG=document.querySelector(“…”),//内联SVG元素
    tgtImage=document.querySelector(“…”),//在何处绘制结果
    can=document.createElement('canvas'),//未显示在页面上
    ctx=can.getContext('2d'),
    加载器=新图像;//第页未显示
    loader.width=can.width=tgtImage.width;
    loader.height=can.height=tgtImage.height;
    loader.onload=函数(){
    ctx.drawImage(加载器,0,0,加载器.宽度,加载器.高度);
    tgtImage.src=can.toDataURL();
    };
    var svgAsXML=(新的XMLSerializer).serializeToString(mySVG);
    loader.src='data:image/svg+xml',+encodeURIComponent(svgAsXML);
    
    但是,这个答案(以及所有仅客户端的解决方案)要求浏览器支持SVG,这可能会使它无法满足您的特定需求

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


    编辑2:通过对Chrome和Firefox的改进,解决了另一个问题中描述的问题。对于Firefox,
    元素必须具有
    width=“…”height=“…”
    属性,才能将其绘制到画布上,这仍然存在限制。Safari目前会在您绘制任何SVG时污染整个画布(无论其来源如何)。但是。

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

    另外,我只在铬合金上测试过

    // 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);
    }
    
    //将SVG元素作为目标
    函数svg_到_png_数据(目标){
    var ctx、mycanvas、svg_数据、img、child;
    //将CSS样式展平到SVG中
    对于(i=0;i
    这是一个相当古老的代码段,但我发现一个更简单的代码段可以在现代浏览器中正确地完成这项工作:

    我使用上面的@Phrogz代码并制作了一个工作代码段。不确定
    mySVG.clientWidth
    是否在FF中工作。也可在此处获取-

    var mySVG=document.querySelector('#svblock'),//内联SVG元素
    tgtImage=document.querySelector(“#diagram_png”),//在何处绘制结果
    can=document.createElement('canvas'),//未显示在页面上
    ctx=can.getContext('2d'),
    加载器=新图像;//第页未显示
    //loader.width=can.width=tgtImage.width=mySVG.getBBox().width;
    //loader.height=can.height=tgtImage.height=mySVG.getBBox().height;
    loader.width=can.width=tgtImage.width=mySVG.clientWidth;
    loader.height=can.height=tgtImage.height=mySVG.clientHeight;
    loader.onload=函数(){
    ctx.drawImage(加载器,0,0,加载器.宽度,加载器.高度);
    tgtImage.src=can.toDataURL();
    };
    var svgAsXML=(新的XMLSerializer).serializeToString(mySVG);
    loader.src='data:image/svg+xml',+encodeURIComponent(svgAsXML)
    
    
    区块诊断
    发现
    执行
    报告
    
    这是一个很好的复制品。Mozilla写了一份关于如何充分做到这一点的漂亮白皮书,如下:。如果没有您建议的操作步骤,我不会找到它。我刚刚发布了一些关于如何使用d3.js执行此操作的示例代码。请注意,在撰写本文时,根据本网站上的几个相关问题,当前版本的iOS(iOS 7)似乎无法从画布中获取有效的数据URL。@c