I am new to JavaFX 2.2 and as of now I couldn't find a way to display SVG Images in my JavaFX 2.2 application. I took a look at Batik, but it didn't do the trick for me as it converts to BufferedImages
and not to javafx.ImageView
.
Is there any way to display an SVG image in an JavaFX application? Or can you at least export an SVG image from JavaFX? Does the function Node.snapshot()
help there in any way?
SVG (Scalable Vector Graphics) is an XML based language to define vector based graphics. In JavaFX we can construct images by parsing SVG paths. Such shapes are represented by the class named SVGPath. This class belongs to the package javafx.
Create a FileInputStream representing the image you want to load. Instantiate the Image class bypassing the input stream object created above, as a parameter to its constructor. Instantiate the ImageView class. Set the image to it by passing above the image object as a parameter to the setImage() method.
The ImageView is a Node used for painting images loaded with Image class. This class allows resizing the displayed image (with or without preserving the original aspect ratio) and specifying a viewport into the source image for restricting the pixels displayed by this ImageView .
Is there any way to display an SVG image in an JavaFX application?
Here are some options:
Or can you at least export an SVG image from javafx?
This feature sounds like a JavaFX SceneGraph to svg converter. While it is theoretically possible, I am not aware that anybody has created such a tool yet.
Does the function Node.snapshot() help there in any way?
Node.snapshot() will not help with exporting an svg image from a JavaFX scene graph as svg is a vector based format and a node snapshot is a bit mapped format.
I took a look at Batik, but it didn't do the trick for me as it converts to BufferedImages and not to javafx.ImageView.
You can easily convert between awt BufferedImages and javafx images using SwingFXUtils.
In terms of performance - which way would you recommend?
For complex svg's, rather than rendering from fxml, you will probably get better performance rendering to a bitmapped image or canvas graphics context. This is because your scene graph will end up a lot simpler, with far less nodes - which means that the javafx runtime will have a lot less work to do. For simple svgs (< 1000 nodes generated), it probably won't matter too much.
Is converting an SVG to an FXML about creating instances of javafx.scene.shape.SVGPath?
Partially. The full SVG specification covers much more ground than the basic shapes. In addition gradients, effects, animations, etc can be performed by an SVG. So if the source SVG image includes those additional items, then they also need to be converted to FXML (as best they can be, there will be some aspects of SVG such as scripting which would be hard to translate to FXML).
My guess is that the size and complexity of the SVG specification is one of the reasons why no direct support for the full SVG image system is currently included in the JavaFX core API and, instead, only limited similar functionality such as SVGPath is offered. Implementing SVG natively in the JavaFX core API would have been high cost for relatively little reward when compared to other desirable items.
If that is the case, wouldn't #2 (and #3) and #5 be just the same?
No. The NetBeans and Eclipse tools referenced in #2 and #3 were more functional than just the SVGPath facilities mentioned in #5, as those tools converted additional aspects of the the SVG specification to FXML equivalents (e.g. gradients, effects and transforms).
I used the transcoder class above to create a little project on github that adds SVG support to JavaFX (JavaFX 8 though): javafxsvg
After calling
SvgImageLoaderFactory.install();
you can use SVG images anywhere in your Java code or CSS just like any other supported image type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With