Marcos
Marcos

Reputation: 5017

Convert SVG to javafx.Image

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.

Upvotes: 1

Views: 4783

Answers (2)

Jan Gassen
Jan Gassen

Reputation: 3534

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.

Upvotes: 3

José Pereda
José Pereda

Reputation: 45456

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();
}

Upvotes: 2

Related Questions