thechiselgroup / biomixer

BioMixer
http://bio-mixer.appspot.com/
16 stars 13 forks source link

JPEG Export #533

Closed everbeek closed 9 years ago

everbeek commented 9 years ago

Find a library that can do SVG to JPEG export, without doing a screen capture.

everbeek commented 9 years ago

The first step, of getting SVG to a PNG in another tab, was tricky. Now I am trying to get the SVG ot be correct. Currently, lines and labels are completely broken. I believe that CSS styles from the stylesheet are not inheriting into the SVG, so when it gets converted to PNG, we do not get what we visually see.

This might allow me to pull the styles down into the SVG markup: https://github.com/moagrius/copycss If I do that, I probably want a clone of the graph, which I can delete after, so that I do not bloat the live one sigh.

The copyCSS did not achieve what I needed. The canvas version of the cloned and property copied SVG still has no arcs, and the labels are miniscule, practically invisible.

everbeek commented 9 years ago

If canvg can be used in browser, it could work. It is an SVG renderer to canvas...so it might do what I need done. https://github.com/gabelerner/canvg

Did not help. Still need to reify classes into markup styles.

Next, looking at and CSS in SVG from here https://css-tricks.com/using-svg/

everbeek commented 9 years ago

Move the button.

Get the code shared with the world somewhere in addition to in the Biomixer repo. Respond to questions on stackoverflow sharing my success.

Oh, no, I think I need to go back to trying canvg with the solution I have. Things are not right in Firefox and IE, of course. I jumped the gun. But at least it was working in Chrome!

everbeek commented 9 years ago

I need to append the canvas, and maybe the image too, in order to get it to work in Firefox. IE still has another problem. Firefox is showing red font, which is some sort of styling issue.

Cannot seem to fix. I am coming back to this some other time, after I fix some other issues.

everbeek commented 9 years ago

Looking into the issue with IE first, in case that solution is usable for Firefox and magically resolves the styling problem.

everbeek commented 9 years ago

IE has a cross domain canvas tainting mechanism. Once a canvas is written to from anything outside the domain of the page, it cannot have things extracted back out of it.

http://stackoverflow.com/questions/18112047/canvas-todataurl-working-in-all-browsers-except-ie10

This page describes a method using a server round-trip: http://danielmclaren.com/node/90

People seem to be saying that there is no way to do it only on browser side for IE. I will keep looking, because I find that to be amazing.

everbeek commented 9 years ago

Maybe Fabric.js or Raphel.js help? http://stackoverflow.com/questions/17817882/pushing-d3-js-output-through-fabric-js-for-ie8-support

Test things in here: http://fabricjs.com/kitchensink/ Jam in the reified CSS styled SVG into that, and if it works, I have a solution for IE I think!

Rectangles would not render, nor labels. Could have been put off screen? But also, the arc lines are very jagged. Are there fabric.js anti-aliasing options? And if I need to make big SVG changes to use this solution, I cannot see if it's the case and if it will be worth it.

everbeek commented 9 years ago

Another shot: http://stackoverflow.com/questions/633724/internet-explorer-todataurl-alternative Use the new page via img described here, see if it ends up differently.

Nope.

everbeek commented 9 years ago

Yet another shot: http://pablojs.com/api/ [ see toImage() and download() ]

everbeek commented 9 years ago

I feel like the way I am using Pablo for this is close to the solution, but currently it only works in Chrome, still. FF and IE might be within reach.

everbeek commented 9 years ago

Ah, Pablo has getBBox() usage that doesn't work in FF. I recall modifying another library to deal with this problem before. Looking at what I did for that.

Was having problems with FF failing to load JS with circular dependencies, but it turns out it was only when Firebug was activated. Great.

everbeek commented 9 years ago

Have it showing up in FF< except that font and triangle menu markers are red. This could be due to background being set to black in the main window (rather than default red as when a browser tab first loads), or it could be due to a font and fill style not making it's way into the SVG I send to the pablo library. I think the former. Checking...

It was sort of the first probem, but it's really that in the clone process, hard coded attributes are not being copied over, only classes. Fixing that...

everbeek commented 9 years ago

None of the color attributes appear to show up in the svg text elements when I gather the computed styles. They show up in the other element types. I found advice to use color isntead of fill and stroke, but it doesn't work.

everbeek commented 9 years ago

GOT IT! The fill was not copying over, so I added color earlier, on someone's advice. that did nothing, but just now I added stroke for the text, and that made the labels super heavy. But, they export with the correct color! Setting stroke width to 0 will likely give me what I need. This was painful. Fill worked for the SVG render, but not the conversion to PNG. Why???

everbeek commented 9 years ago

Finally got it working for Firefox, but IE is worse off. I want to keep the changes I have made out of the repo for now, to assist me in meeting IE's demands, possibly with code I have commented out. It will be easier to see what I have done if it's not committed and pushed yet.

everbeek commented 9 years ago

It appears that IE refuses to load my image. I tried different ways, and couldn't get it to work. The old way of setting the src to a data url does not work due to cross site scripting limitations. I will continue trying different things (and while making sure I don't break existing functionality for FF and Chrome).

everbeek commented 9 years ago

Ok, clearly Pablo.js does not support toIamge() for non-SVG in IE. In the test page it lists support for PNG and JPEG, but on the API live code page, adding "png" to the toImage() call does not work out in IE, but does in Firefox.

http://pablojs.com/tests/ http://pablojs.com/api/toImage/

I cannot support SVG to PNG or JPEG in IE.

Shall I therefore allow download of the SVG, which the user can convert manually?

This first answer here claims to have document.write() working with canvas.toDataUrl(). I will test his formulation, but I don't expect it to work for me: http://stackoverflow.com/questions/21860633/download-canvas-to-image-in-ie-using-javascript

everbeek commented 9 years ago

I am still trying. I am desperate.

" it does seem that if you load a base64 encoded image into a canvas in IE10 then it taints the canvas and you can no longer call toDataUrl on the canvas" This is what I understood, and reading that quote, I think that if there was a utility to actually parse SVG into canvas, without any base64 encoded conversion, then the canvas should not be tainted, and using the data url should work. But didn't I have CORS problems too? I can test by grabbing the dataurl from Chrome, and manually putting it into the page for IE to use. If that works, then using an untainted canvas, derived from some magical library that parses SVG to canvas, should work.

everbeek commented 9 years ago

Save without displaying! Pablo.js can do this for Chrome and FF, but not for IE. But there is a solution here that the author says will work for IE using canvas-toBlob.js and FileSaver.js, which he claims will avoid any tainted canvas issues! Checking!

http://stackoverflow.com/questions/27492807/image-download-from-canvas-doesnt-work-in-ie-11

everbeek commented 9 years ago

Yet another lead, from a blog, using canvg: http://it-supernova.com/convert-svg-to-png-using-canvas/

I checked canvg before. It may have been that it didn't support my styles properly...but looking again, because I may have style bugs when I tried it.

No, it looks like canvg is not complete, and cannot parse all of SVG. Something in the graph is beyond its parsing maturity.

everbeek commented 9 years ago

I think I have to make IE export the SVG as it is, and advise the user to convert it with another program.

everbeek commented 9 years ago

Two things: FlashCanvas, to circumvent the canvas taint security in IE, and the svg string for the cloned svg structure is empty. Sort those both out, and IE will probably have functioning export!

everbeek commented 9 years ago

In IE, there are no children available in the SVG when I set the string via html(), and text() doesn't do it, despite advice to do that. Also, when I do text() at all, it breaks Chrome png export entirely. Trying to find the way to successfully clone svg in IE.

Still working this out. If I get it functioning for IE, I will need to provide backup for users without Flash Player installed, where the file offered is in SVG, and a message informs them that their browser does not support the conversion of web graphics to an image. It can then advise them that they may use another browser, download the provided SVG and convert as necessary, or use their OS screen capture facilities.

I can't believe that IE is making it so that I have to provide detailed instructions on a work around for end users...

The Flash plugin is not being detected, and FlashCanvas isn't used if it isn't. Why is it not showing up? v17 (current) is in use in my IE...

everbeek commented 9 years ago

Still trying to see why my svg doesn't work in IE even when the butterfly does. Finally found a library intended to specialize in converting SVG to PNG. I might assess it, but it doesn't do IE in any case.

It is good for testing my svg for rendering in a different context than my own code: http://exupero.org/saveSvgAsPng/

everbeek commented 9 years ago

Might need an svg shim for setting inner html: https://github.com/mbostock/d3/wiki/Selections#html

It works without the shim in Chrome and FF, but doesn't seem to in IE.

everbeek commented 9 years ago

Holy moly! I finally have it! I needed to use canvg, since it parses SVG into its own canvas, and thus the canvas is not tainted by importing SVG into it. Please no one inform Microsoft that canvg is exploiting a security hole in order to allow SVG to image export...

A bug in canvg was preventing it from working, but I have IE emitting PNG from SVG. I had it working with the butterfly svg for a bit, then just now with a hard coded sample graph.

Now to do with the exact graph rather than hard coded, then clean it all up and commit.

After that, I need to fix a problem with font size in the IE emitted SVG.

everbeek commented 9 years ago

Got it. Done. Deploying for Cassie.

codeSasquatch commented 8 years ago

Your my Hero, I went through a very similar process as you and found your journey after a couple days of IE issues.

everbeek commented 8 years ago

I'm glad you came across this! I am having flashbacks looking over my comments here. It was hairy!

codeSasquatch commented 8 years ago

Thanks for posting it!