Saving raphaeljs image as png on Internet Explorer

733 views
Skip to first unread message

Michał Nowotka

unread,
Nov 7, 2010, 11:13:54 AM11/7/10
to raph...@googlegroups.com
Hello,
I have some nice graphics done using raphaeljs and I want to add a
feature to save it as a PNG. This is simple on every browser except IE
because on non-IE browsers I get SVG as an output from raphael, then I
can convert it to canvas (using cansvg library) and canvas has
toDataURL() method. But on IE raphael outputs VML. I can't use chrome
frame plugin. Why? Users of my application choose IE just because it
is preinstalled on Windows and they don't have permission to install
anything else. So they can't install this plugin. So my second idea
was to get SVG string on IE, pass it to cansvg to get canvas and then
use flashCanvas. I tried to trick raphael to think it's running on
non-IE browser and get SVG as output but I failed as raphael use some
js functions that are absent in IE to produce SVG. So for now I have
no idea how to accomplish this task under IE. Do you have some?

PS. I asked the same question here:
http://stackoverflow.com/questions/4118134/saving-raphaeljs-image-as-png-on-internet-explorer

--
Regards,

Michał Nowotka

Ed Davies

unread,
Nov 7, 2010, 3:24:55 PM11/7/10
to Raphaël
On Nov 7, 4:13 pm, Michał Nowotka <mmm...@gmail.com> wrote:
> ... I tried to trick raphael to think it's running on
> non-IE browser and get SVG as output but I failed as raphael use some
> js functions that are absent in IE to produce SVG.

I don't know what those functions are but is there any chance of
providing your own versions on IE? Generally speaking the
functionality is usually available on IE, just in a different form.

Michał Nowotka

unread,
Nov 7, 2010, 3:40:11 PM11/7/10
to raph...@googlegroups.com
Look at the goal i want to achieve - I don't want to create similar
functionality. I just want to get string that is valid svg file. I
know that IE won't interpret it, but cansvg on input gets svg string
and on output it writes to canvas. And canvas support can be achieved
in IE using flashCanvas.

Ed Davies

unread,
Nov 8, 2010, 8:24:30 AM11/8/10
to Raphaël
Well, I thought a sub-goal was to create an SVG string on IE and so a
sub-sub-goal was to produce an SVG DOM on IE using Raphaël. Providing
the functions that Raphaël uses to produce the SVG DOM seems like a
sensible sub-sub-sub-goal to me. Am I missing something?

Michał Nowotka

unread,
Nov 8, 2010, 10:33:46 AM11/8/10
to raph...@googlegroups.com
If I had SVG string as an output of raphael on IE I would accomplish
my task very easy so we can say this is my main goal ;)
But I don't think playing with DOM is a subgoal as in my opionion it
can be achived without it. Now I'm thinking about different solution.
Raphael keeps track of every object on the canvas in some internal
structure that can be accessed via "paper" object. Maybe the best
solution is just to iterate over it and extract all attributes of
every object making SVG string. I don't see any simpler solution. It
would be nice if Raphael had some string buffer constning svg string
of current state of scene.

--
Regards

Michał Nowotka

Ed Davies

unread,
Nov 8, 2010, 5:50:34 PM11/8/10
to Raphaël
Taking some of your points out of order:

> It
> would be nice if Raphael had some string buffer constning svg string
> of current state of scene.

Maybe nice for your particular use case but a pointless waste of time
and memory for normal operation. Browsers don't display from text
strings, they display from DOM structures.

> If I had SVG string as an output of raphael on IE I would accomplish
> my task very easy so we can say this is my main goal ;)

OK, delete one "sub" from each of uses of "sub-*goal". ;)

> Raphael keeps track of every object on the canvas in some internal
> structure that can be accessed via "paper" object. Maybe the best
> solution is just to iterate over it and extract all attributes of
> every object making SVG string. I don't see any simpler solution.

Why is that simpler than letting Raphaël build the DOM as normal then
asking the browser for the string representation of it? If the
required routines to allow Raphaël to build an SVG DOM on IE can be
implemented relatively easily (I suspect, but don't know, that they
can) then that should be fairly simple and robust. Fishing around in
Raphaël's internal data seems to me to be asking for trouble with
future versions.

Ethan Jucovy

unread,
Nov 8, 2010, 5:58:54 PM11/8/10
to raph...@googlegroups.com
2010/11/8 Michał Nowotka <mmm...@gmail.com>:

> If I had SVG string as an output of raphael on IE I would accomplish
> my task very easy so we can say this is my main goal ;)
> But I don't think playing with DOM is a subgoal as in my opionion it
> can be achived without it. Now I'm thinking about different solution.
> Raphael keeps track of every object on the canvas in some internal
> structure that can be accessed via "paper" object. Maybe the best
> solution is just to iterate over it and extract all attributes of
> every object making SVG string.

The raphael.serialize plugin takes this approach:

https://github.com/jspies/raphael.serialize

It iterates over all the objects, extracts the interesting attributes,
and builds a JSON object. The use-case is to send that JSON to a
server which can then reconstruct the SVG, convert it to a raster
format and serve the resulting image file. But, if you have a way to
do this all client-side from an SVG string, that ought to work.

Anyway, I've been using raphael.serialize for this purpose. It's not
complete, there are some node-type cases missing, but the approach
isn't hard. (If you look at the raphael.serialize code, it's very
straightforward and short.) In my fork of raphael.serialize
(https://github.com/ejucovy/raphael.serialize/) I added a few more
cases and also added some special cases to ignore objects with
display:none, etc.

-Ethan

Michał Nowotka

unread,
Nov 9, 2010, 4:18:51 AM11/9/10
to raph...@googlegroups.com
> Why is that simpler than letting Raphaël build the DOM as normal then
> asking the browser for the string representation of it?  If the
> required routines to allow Raphaël to build an SVG DOM on IE can be
> implemented relatively easily (I suspect, but don't know, that they
> can) then that should be fairly simple and robust.  Fishing around in
> Raphaël's internal data seems to me to be asking for trouble with
> future versions.

It's simpler because I have proof of concept making a SVG string from
raphael done by iterating over elements stored in "paper" just like it
is done in raphael.serialize plugin. IE just does not support SVG.
That is the reason it outputs VML on IE. If the implementation of SVG
for IE was so easy as you think then I suppose author of raphaeljs
would implement it and we would have one consistent SVG format as an
output for every browser. But if you implemented it I would be happy
to see your proof of concept.

>Maybe nice for your particular use case but a pointless waste of time
>and memory for normal operation.

I don't think this is waste of memory as SVG is human readable format
that can be saved, exported, converted to other vector or raster image
files so if raphael don't use SVG on IE (which is understandable as IE
don't support SVG) at least it could give a SVG string as one of it's
native methods.

My question was if synthesizing SVG string from "paper" object is the
simplest method or it could be achieved in a simpler way as I don't
want to reinvent the wheel. I don't want to argue with anybody. I
asked for help not for review of my idea.

--
Regards

Michał Nowotka

Ed Davies

unread,
Nov 9, 2010, 5:28:14 PM11/9/10
to Raphaël
Ahah, this is why we're talking at cross purposes:

On Nov 9, 9:18 am, Michał Nowotka <mmm...@gmail.com> wrote:
> If the implementation of SVG
> for IE was so easy as you think then I suppose author of raphaeljs
> would implement it and we would have one consistent SVG format as an
> output for every browser.

I'm not suggesting implementing SVG on IE.

What I am suggesting is:

1) Trick Raphaël under IE into thinking it's running on an SVG capable
browser, as you have already done.
2) Getting it to create an SVG DOM (which I'm guessing is fairly easy
- you suggest that there are a few routines missing which are needed
for this but won't say what they are).
3) Serializing that SVG DOM into an SVG string to use with the canvas.

I am not suggesting at any point actually displaying the SVG DOM so
there is no need for an SVG "implementation" on IE. All I'm
suggesting is reuse of the existing Raphaël code to generate SVG (in
DOM form which is then converted to string form).

There may be a show-stopper on this, something like IE mishandling of
namepspace in serialization or something, but if there is it isn't
obvious to me at this point.

Ed Davies

unread,
Nov 9, 2010, 5:30:22 PM11/9/10
to Raphaël
I didn't mean "namepspace", obviously.

Clifford Heath

unread,
Nov 9, 2010, 6:23:42 PM11/9/10
to raph...@googlegroups.com
On 10/11/2010, at 9:28 AM, Ed Davies wrote:
> I'm not suggesting implementing SVG on IE.
> 1) Trick Raphaël under IE into thinking it's running on an SVG capable
> browser, as you have already done.
> 2) Getting it to create an SVG DOM

The alternative, which I discussed with Dmitry on IRC yesterday,
is to abstract away the DOM-creation routines in the SVG layer
under an API, so you have methods "createNode", "setAttr" and
maybe another one or two, then you can create an alternate
implementation of that API which directly creates SVG text.

However... do you have to code additional JS to generate the
SVG text? In many cases, it would be desirable to create the
SVG from an existing VML drawing... and then the path taken
by raphael.serialise is much more sensible. Maybe Raphael's
SVG code could be exposed for more re-use, but I now think
the Ed's approach (which I favoured too) is not the right one.

Clifford Heath.

Michał Nowotka

unread,
Nov 10, 2010, 3:46:24 AM11/10/10
to raph...@googlegroups.com
> it would be desirable to create the
> SVG from an existing VML drawing

How to do this? I havn't found any js library converting VML to SVG.
Is there some simple mapping between this formats? i don't think so...

Clifford Heath

unread,
Nov 10, 2010, 5:38:10 AM11/10/10
to raph...@googlegroups.com

I mean from the Raphael objects that were used to create a VML drawing.
Yes, it's possible by bringing the existing SVG mapper into play on
those
Raphael objects (and modifying it to it produces SVG text, not SVG DOM),
but as I said, probably not the best idea.

Clifford Heath.

Adam

unread,
Nov 10, 2010, 4:29:14 PM11/10/10
to Raphaël
Hi Guys,

I had the same requirement for a project I did a while back. It was
basically a project that used Raphael to design a personalise Post-it
note and then generate a PDF proof of it.

I found there was two options to get what you want, but they were not
perfect and were quite hacky, but hopefully they may be of use. (some
are discussed above)

The option I found worked best was this:
- When the objects were created on the screen I would save them as
Javascript objects and then store them in a database on a save.
- Raphael would generate SVG or VML depending on browser and display
on screen.
- On a next step I would send the user to a file that included a copy
of the Raphael Javascript file, but hacked so it would always produce
SVG and do no browser detection.
- I then wrote a script that used this version of Rapahel to rebuild
the Javascript objects I saved and generate the SVG.
- I then used a bit of JQuery to get the SVG code and hey presto.
- I then used Imagick and later Batik to convert the SVG to a PNG.

The other option, which I played with was to use a VML to SVG
conversion script. One that seemed to work best was
http://sourceforge.net/projects/vectorconverter/.
I would store the VML or SVG script and if there was a VML I would
convert it.

To get your SVG to PNG I found Image Magick worked well, but was not
perfect. I then stumbled upon Batik, which was brilliant. Converted
SVG to PNG perfectly. It can be tricky to install on a server though.

Hope that helps.

Cheers

Adam

Clifford Heath

unread,
Nov 10, 2010, 4:39:47 PM11/10/10
to raph...@googlegroups.com
On 11/11/2010, at 8:29 AM, Adam wrote:
> - On a next step I would send the user to a file that included a copy
> of the Raphael Javascript file, but hacked so it would always produce
> SVG and do no browser detection.

Did this work by producing SVG DOM nodes (createElement, etc), or
did you have it to produce SVG text directly?

If the latter, can you share your hacked version?

Clifford Heath.

Michał Nowotka

unread,
Nov 10, 2010, 5:13:30 PM11/10/10
to raph...@googlegroups.com
2010/11/10 Adam <in...@niddocks.co.uk>:

> Hi Guys,
>
> I had the same requirement for a project I did a while back.

I have very different requrement - all plotting must be done on the client side.

> --
> You received this message because you are subscribed to the Google Groups "Raphaël" group.
> To post to this group, send an email to raph...@googlegroups.com.
> To unsubscribe from this group, send email to raphaeljs+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/raphaeljs?hl=en-GB.
>
>

--
Pozdrawiam

Michał Nowotka

Reply all
Reply to author
Forward
0 new messages