我使用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下完成此任务?
答案 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!):
启动空白画布
<canvas id="myCanvas"></canvas>
使用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");
使用Raphael Export将纸张从VML转换为SVG。
var svg = paper.toSVG();
在空白画布上初始化Flashcanvas
var canvas = document.getElementById('export');
if (typeof FlashCanvas != "undefined") {
FlashCanvas.initElement(canvas); //initiate Flashcanvas on our canvas
}
将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);
}
});
一旦canvg在画布上生成了SVG数据,请调用Flashcanvas的canvas2png函数
//This is called within the renderCallback canvg function above:
renderCallback: function() {
setTimeout(function() {
canvas2png(canvas);
}, 1000);
}
纸张保存为PNG! $$$
<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麻烦):
答案 3 :(得分:0)
您可能希望在服务器端生成图像。浏览器对生成图形的支持仍然非常有限。
Node Canvas刚刚出来,我过去使用过ImageMagick并取得了巨大的成功。