Convert SVG to javafx.Image


Question

I need to convert SVG file to a javafx.Image. I try:

    WebView wb = new WebView();

    wb.getEngine().load(Funciones.class.getResource("/com/img/Dibujo.svg").toExternalForm());
    wb.setMinSize(125, 125);
    wb.setMaxSize(125, 125);
    wb.setPrefSize(125, 125);
    Scene scene = new Scene(wb);
    WritableImage img = new WritableImage(125, 125);
    scene.snapshot(img);

    File file = new File("CanvasImage.png");

    try {
        ImageIO.write(SwingFXUtils.fromFXImage(img, null), "png", file);
    }
    catch (Exception s) {
    }

But always, I get a white image. I use webview in some panels to load's svg and works fine, but I don't know why not works to write to a file.

NOTE: I show a stage with webview control, and Image loads OK, but I discover that fails on save to file, because webview load content take place in a thread so I need to control when load is finish, but I don't know how.

1
0
11/15/2014 5:54:26 PM

Accepted Answer

You need to show the webview on the scene, because it doesn't work headless.

And if, as you say, you are showing the webview, first you have to wait till the load has finished. But you can't perform the snapshot inmediately, or you will get a white image.

The trick is to add some delay:

@Override
public void start(Stage primaryStage) {
    WebView wb = new WebView();
    WebEngine webEngine = wb.getEngine();

    Scene scene = new Scene(wb, 125, 125);

    webEngine.getLoadWorker().stateProperty().addListener((obs,oldState,newState)->{
        if(newState==State.SUCCEEDED){
            final PauseTransition pause = new PauseTransition(Duration.millis(500));
            pause.setOnFinished(e->{
                WritableImage img = new WritableImage(125, 125);
                scene.snapshot(img);

                File file = new File("CanvasImage.png");

                try {
                    ImageIO.write(SwingFXUtils.fromFXImage(img, null), "png", file);
                    }
                catch (Exception s) {
                }   
            });
            pause.play(); 
        }
    });
    webEngine.load(getClass().getResource("/com/img/Dibujo.svg").toExternalForm());

    primaryStage.setScene(scene);
    primaryStage.show();
}
1
5/23/2017 11:58:45 AM

If you just want to use any SVG image within your application where JavaFX requires an JavaFX Image object, you can also use this library https://github.com/codecentric/javafxsvg

After calling

SvgImageLoaderFactory.install();

you can than simply use

Image image = new Image("Dibujo.svg");

It uses http://xmlgraphics.apache.org/batik/ internally, which you can of you can, of course, also use individually just to convert your SVGs into any other image format in Java.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon