在Internet Explorer上将Raphaël图像保存为PNG

时间:2010-11-07 14:26:40

标签: javascript canvas raphael vml

我使用Raphaël(一个JavaScript库)完成了一些漂亮的图形处理,我想添加一个功能,将其保存为PNG文件。

除了Internet Explorer之外,每个浏览器都很简单,因为在非Internet Explorer浏览器中,我得到了SVG作为Raphaël的输出,然后我可以将它转换为canvas(使用cansvg库)并且canvas具有toDataURL()方法。但在Internet Explorer上,Raphaël输出VML。我无法使用Chrome框架插件。为什么?

我的应用程序的用户选择Internet Explorer只是因为它预装在Windows上,并且他们无权安装任何其他内容。所以他们无法安装这个插件。所以我的第二个想法是在Internet Explorer上获取SVG字符串,将其传递给cansvg以获取画布,然后使用flashCanvas

我试图欺骗Raphaël认为它在非Internet Explorer浏览器上运行并获得SVG作为输出,但我失败了,因为Raphaël使用了一些在Internet Explorer中不存在的JavaScript函数来生成SVG。

那么如何在Internet Explorer下完成此任务?

4 个答案:

答案 0 :(得分:2)

Raphaël在Internet Explorer中使用VML,在所有其他浏览器中使用SVG。 Canvas具有作为图像导出的内置功能,因为此功能不是在VML中构建的。您可以使用服务器端代码为不受支持的浏览器实现相同的功能。

另一种解决方案是使用可以从VML生成图像的Internet Explorer的ActiveX解决方案。其中一个解决方案是HTML Snapshot ActiveX Component

通常,除非绝对必要,否则不建议实施ActiveX解决方案。

答案 1 :(得分:2)

RaphaelJS不使用画布。 它在IE中使用VML,在所有其他浏览器中使用SVG。

正如OP所说,您可以获取原始SVG(因为它是一个完整的SVG文档)并下载它,他正在寻找与VML类似的功能。

我能想到的唯一方法是让IE将VML数据(如果可能的话)发送回服务器,该服务器转换为PNG并下载它。

但是,如果你想要一个PNG,你可能最好从一开始就使用画布,因为如果你转换成位图,你可能不需要图形的矢量面。 Checkout画布和google IE画布脚本,看看你是否可以使用它。

至于“用于生成图形的浏览器支持仍然非常有限”,事实并非如此。查看RaphaelJS.com演示,这是完全可行的,也是一个很好的解决方案。唯一的问题是IE< 9,它没有采用任何现代技术,如HTML5,CSS3或SVG。

任何支持Canvas或google IEcanvas的东西也可以产生不错的结果。

答案 2 :(得分:2)

PHP& JavaScript解决方案(不需要ImageMagick,Apache Batik Rasterizer或Inkscape!):

要求

  1. PHP
  2. Flash Player 9+(对于Flashcanvas,如果我错了,请纠正我)
  3. RaphaelJS
  4. Raphael Export
  5. CanVG
  6. FlashCanvas Free or Pro
  7. Canvas2PNG + save.php(包含在FlashCanvas中)
  8. 概述

    1. 启动空白画布
    2. 使用Raphael绘制一些VML
    3. 使用Raphael Export将纸张从VML转换为SVG
    4. 在空白画布上初始化Flashcanvas
    5. 将Raphael Export中的SVG字符串发送到canvg
    6. 一旦canvg将SVG数据生成到FlashCanvas启动的画布上,请调用Flashcanvas'bark2png函数
    7. 纸张保存为PNG! $$$
    8. 击穿

      1. 启动空白画布

        <canvas id="myCanvas"></canvas>
        
      2. 使用Raphael绘制一些VML

        //Basic Example
        var paper = Raphael(10, 50, 320, 200);
        var circle = paper.circle(50, 40, 10);
        circle.attr("fill", "#f00");
        circle.attr("stroke", "#fff");
        
      3. 使用Raphael Export将纸张从VML转换为SVG。

        var svg = paper.toSVG();
        
      4. 在空白画布上初始化Flashcanvas

        var canvas = document.getElementById('export');
        if (typeof FlashCanvas != "undefined") {
          FlashCanvas.initElement(canvas); //initiate Flashcanvas on our canvas
        }
        
      5. 将Raphael Export中的SVG字符串发送到canvg

        canvg(canvas, svg, {
          ignoreMouse: true, //I needed these options so Internet Explorer wouldn't clear the canvas
          ignoreAnimation: true,
          ignoreClear: true,
          renderCallback: function() {
            setTimeout(function() {
              canvas2png(canvas);
            }, 1000);
          }
        });
        
      6. 一旦canvg在画布上生成了SVG数据,请调用Flashcanvas的canvas2png函数

        //This is called within the renderCallback canvg function above:
        renderCallback: function() {
          setTimeout(function() {
            canvas2png(canvas);
          }, 1000);
        }
        
      7. 纸张保存为PNG! $$$

      8. 注释/调查结果

        • 不要使用FLASHCANVAS包含/使用EXCANVAS ,我犯的这一行错误几乎让我在很多场合放弃了FlashCanvas。
        • Flashcanvas应该尽早包含在<head>中,出于某些原因,我在以后包含flashcanvas.js时遇到了问题。
        • Canvas2png.js默认会提示用户保存.png文件。或者,您可以通过编辑来自的Flashcanvas save.php文件将.png写入您的服务器:

          readfile('php://input');
          

          //Comment these out so that the download is not forced
          //header('Content-Type: application/octet-stream');
          //header('Content-Disposition: attachment; filename="canvas.png"');
          
          $putdata = fopen("php://input", "r");
          $fp = fopen("path/to/image_name.png", "w");
          while ($data = fread($putdata, 1024)) {
            fwrite($fp, $data);
          }
          fclose($fp);
          fclose($putdata);
          
        • 在最后一点之后:如果您选择将图像保存到服务器,默认情况下,当您调用canvas2png()时,您将被转发到空白的save.php(save.php不是由AJAX运行的) !)因此你将失去当前的拉斐尔绘画课程。

        因此,如果您想在不丢失当前Raphael会话的情况下调用此方法,我解决此问题的方法是将Raphael Paper保留在一个页面上,并在<canvas>页面上保留另一个。

        一般的想法是,您在主页上保留Raphael绘图活动,当您准备导出/保存图像时,可以打开一个包含空画布的新窗口,并将 SVG数据发送到该新临时页面。从那里开始,除了在新窗口中,您可以再次按照我们离开的步骤再次执行步骤,并且在生成并保存图像时,在save.php文件的末尾,您可以使用javascript调用:{{1}关闭那个新窗口。

        我们需要弹出这个新窗口,以便可以使用SVG数据正确处理画布。

        • 使用Internet Explorer 8(Chrome / Firefox工作)的canvg无法读取从.php URL生成的图像,为了解决此问题,我必须使用PHP将“php url图像内容”保存为服务器上的临时映像,并通过替换原始 xlink:href 将该临时映像用作SVG数据的参考。

        • canvas2png.js会在您的浏览器支持self.close()的情况下退回,使此解决方案与浏览器兼容

        • 作为最后一点,如果您使用支持toDataURL的浏览器,我认为我会包含导出图片的快捷方法,我推断浏览器也支持SVG ,因此保存图像的过程要容易得多(不需要Flashcanvas麻烦):

          1. 启动空白画布
          2. 使用Raphael绘制一些SVG
          3. 使用Raphael Export
          4. 导出SVG字符串
          5. 使用canvg将SVG数据解析为空白画布
          6. 使用canvas.toDataURL()

答案 3 :(得分:0)

您可能希望在服务器端生成图像。浏览器对生成图形的支持仍然非常有限。

Node Canvas刚刚出来,我过去使用过ImageMagick并取得了巨大的成功。