在 Internet Explorer 上将 Raphaël 图像保存为 PNG
Posted
技术标签:
【中文标题】在 Internet Explorer 上将 Raphaël 图像保存为 PNG【英文标题】:Saving Raphaël image as PNG on Internet Explorer 【发布时间】:2010-11-07 14:26:40 【问题描述】:我使用 Raphaël(一个 javascript 库)完成了一些漂亮的图形,我想添加一个功能以将其保存为 PNG 文件。
这在除 Internet Explorer 之外的所有浏览器上都很简单,因为在非 Internet Explorer 浏览器上我得到 SVG 作为 Raphaël 的输出,然后我可以将其转换为画布(使用 cansvg 库)并且画布有一个 @987654326 @ 方法。但在 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 下完成这项任务呢?
【问题讨论】:
我不会将此作为答案发布,因为我自己没有尝试过,但您可能会成功“欺骗”拉斐尔使用 svg-web,它对 SVG 有很好的支持DOM API。您在其他浏览器中使用的技术将是相同的。我认为这是可以工作的,但你可能不得不稍微修改一下 raphaeljs 代码。请注意,我从未读过任何人尝试将 raphaeljs 与 svg-web、svg-web 与 canvg 或 canvg 与 flashcanvas 一起使用,因此,如果您让这一切正常工作,这将是一个史诗般的 hack,您绝对应该写它。祝你好运:) 正如我所说的 - 我让它在除 IE 之外的所有浏览器上都能运行。如果你想试试,我可以附上 aptana 项目。 现在是关于欺骗拉斐尔的事情。这些是 raphael 中使用的方法,IE 不支持:getNumberOfChars()、getExtentOfChar()、createElementNS() 以及其他一些问题 【参考方案1】:RaphaelJS 不使用画布。 它在 IE 中使用 VML,但在所有其他浏览器中使用 SVG。
正如 OP 所说,您可以获取原始 SVG(因为它是一个完整的 SVG 文档)并下载它,他正在寻找与 VML 类似的功能。
我能想到的唯一方法是让 IE 将 VML 数据(如果可能的话)发送回服务器,该服务器将其转换为 PNG 并下载它。
但是,由于您需要 PNG,因此您可能最好从一开始就使用画布,因为如果您随后转换为位图,则可能不需要图形的矢量端。检查画布和谷歌 IE 画布脚本,看看你是否可以使用它。
至于“浏览器对生成图形的支持仍然非常有限”,事实并非如此。查看 RaphaelJS.com 演示,这是完全可行的,也是一个很好的解决方案。唯一的问题是 IE
任何支持 Canvas 或 google IEcanvas 的东西也能产生不错的结果。
【讨论】:
Excanvas 非常糟糕,Raphael 要好得多。话虽如此,我刚刚开始尝试将拉斐尔的画作保存为 IE 中的图像 :)。 我没用过,但是这个sourceforge.net/projects/vectorconverter现在已经存在了,可以修改来做你需要的事情【参考方案2】:Raphaël 在 Internet Explorer 中使用 VML,在所有其他浏览器中使用 SVG。 Canvas 具有导出为图像的内置功能,而 VML 中未内置此类功能。对于不受支持的浏览器,您可以使用服务器端代码来实现相同的功能。
另一种解决方案是使用 Internet Explorer 的 ActiveX 解决方案,它可以从 VML 生成图像。一种这样的解决方案是html Snapshot ActiveX Component。
一般来说,除非绝对必要,否则不建议实施 ActiveX 解决方案。
【讨论】:
【参考方案3】:php & JavaScript 解决方案(不需要ImageMagick、Apache Batik Rasterizer 或Inkscape!):
要求
-
PHP
Flash Player 9+(对于 Flashcanvas,如果我错了,请纠正我)
RaphaelJS
Raphael Export
CanVG
FlashCanvas Free or Pro
Canvas2PNG + save.php(包含在 FlashCanvas 中)
概述
-
启动一个空画布
用 Raphael 画一些 VML
使用 Raphael Export 将纸张从 VML 转换为 SVG
在空白画布上初始化 Flashcanvas
将 SVG 字符串从 Raphael Export 发送到 canvg
一旦 canvg 将 SVG 数据生成到 FlashCanvas 启动的画布上,调用 Flashcanvas 的 canvas2png 函数
纸张保存为 PNG! $$$
故障
启动一个空画布
<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
将 SVG 字符串从 Raphael Export 发送到 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! $$$
笔记/发现
不要在 FLASHCANVAS 中包含/使用 EXCANVAS,我犯的这一行错误几乎导致我多次放弃 FlashCanvas。 应尽早将 Flashcanvas 包含在<head>
中,由于某种原因,我在稍后包含 flashcanvas.js 时遇到了问题。
Canvas2png.js 默认会提示用户保存 .png 文件。或者,您可以通过编辑 Flashcanvas save.php 文件 from 将 .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 论文保留在一个页面上,而将 <canvas>
页面保留在另一个页面上。
一般的想法是您将 Raphael 绘图活动保留在主页上,当您准备导出/保存图像时,您可以打开一个包含 空画布的新窗口,并将 SVG 数据 发送到该新的临时页面。从那里你可以再次按照我们离开的步骤,除了在新窗口中,在 save.php 文件的末尾,当图像生成并保存时,你可以使用 javascript 调用:self.close()
到关闭那个新窗口。
我们需要弹出这个新窗口,以便可以使用 SVG 数据正确处理画布。
canvg 与 Internet Explorer 8(Chrome/Firefox 工作)无法读取从 .php URL 生成的图像,要解决此问题,我必须使用 PHP 将“php url 图像内容”保存为服务器上的临时图像,并使用该临时图像作为 SVG 数据的参考,方法是替换其原始 xlink:href。
canvas2png.js 在您的浏览器确实支持toDataURL
的情况下具有后备功能,从而使此解决方案跨浏览器兼容
最后一点,如果您使用支持 toDataURL 的浏览器,我想我会包含导出图像的快速方法,我会推断 浏览器也支持SVG,因此保存图像的过程要容易得多(无需 Flashcanvas 麻烦):
-
启动一个空画布
用 Raphael 绘制一些 SVG
使用 Raphael Export 导出 SVG 字符串
使用 canvg 将 SVG 数据解析到空画布中
使用 canvas.toDataURL()
【讨论】:
【参考方案4】:您可能希望考虑在服务器端生成图像。浏览器对生成图形的支持仍然非常有限。
Node Canvas 刚刚问世,我过去使用 ImageMagick 取得了巨大成功。
【讨论】:
"至于“浏览器对生成图形的支持仍然非常有限”,不是。查看 RaphaelJS.com 的演示,这是完全可行的,也是一个很好的解决方案。唯一的问题是 IE @Alex 他的问题正是如此。 . .他需要支持旧的浏览器。为什么只在后端生成图像然后通过 AJAX 加载它们不是一个好的解决方案?以上是关于在 Internet Explorer 上将 Raphaël 图像保存为 PNG的主要内容,如果未能解决你的问题,请参考以下文章
为啥即使在模拟 Internet Explorer 8 文档模式时,Internet Explorer 11 也不支持条件注释?
对于某些情况,如 Internet Explorer 特定的 CSS 或 Internet Explorer 特定的 JavaScript 代码,如何仅针对 Internet Explorer 10?
如何从 Internet Explorer 11 降级到 Internet Explorer 10?
为啥在安装Windows Internet Explorer 7的时候,提示"此操作系统不支持Windows Internet Explorer 7.