-2

Can I save image from ImageView in JavaFX?

I found way which use ImageIO, but I can't import it in my JavaFX project. I'm using IntelliJ IDEA.

  • 1
    The easiest way is to use `ImageIO`, as you said. You will need to require the `java.desktop` module in your `module-info.Java` file. – James_D Dec 12 '22 at 21:44
  • 1
    See: [How to save a file uploaded by FileChooser to a directory in your project?](https://stackoverflow.com/questions/72294934/how-to-save-a-file-uploaded-by-filechooser-to-a-directory-in-your-project/72311598#72311598) – jewelsea Dec 12 '22 at 22:18
  • 2
    Why do you need to save an image displayed in an ImageView? If the image is displayed in the ImageView, then you already had access to the image to load it into the ImageView. – jewelsea Dec 12 '22 at 22:22

1 Answers1

1

I believe there are many approaches to save an image from a javafx ImageView into a file, but here are the two I could think of :

java.nio.file.Files.copy

This method in the Files utility class allows you to copy bytes from an InputStream into a target path, which can be regarded as saving the image into a file.

The requirements for this to work are that

  • The Image presented in the ImageView was created using a file or a url, not an inputStream.
  • You're using a version of JavaFX that is as or more recent than the one shipped with java 9, because that's when the Image.getUrl() method was introduced.

You need to get the Image object from the ImageView by calling ImageView.getImage() , and then getting the Url from the Image using Image.getUrl() , you can then create a URL with the returned string and then call URL.openStream() to get an InputStream that you can copy bytes from using Files.copy


javafx.embed.swing.SwingFXUtils.fromFXImage

This method provided by the javafx.swing module, converts a JavaFX Image Object to a BufferedImage that you can save to a file using ImageIO.write


I have prepared this code example (that I have tested on my machine and worked as expected) to demonstrate the two approaches

package jfxTest;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

import javax.imageio.ImageIO;

import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class App extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        VBox root = new VBox(15);
        root.setPadding(new Insets(15));
        root.setAlignment(Pos.CENTER);

        ImageView view = new ImageView(new Image(getClass().getResource("/img.jpg").toExternalForm()));
        view.setPreserveRatio(true);
        view.setFitHeight(300);

        Button saveCopy = new Button("save copy");
        Button saveWrite = new Button("save write");

        saveCopy.setOnAction(e -> {
            try {
                File target = new File("saved_using_copy.jpg");
                
                //get Url and open stream
                String urlString = view.getImage().getUrl();
                InputStream inputStream = new URL(urlString).openStream();
                
                //copy bytes from the stream to the target file
                Files.copy(inputStream, target.toPath(), StandardCopyOption.REPLACE_EXISTING);
                
                System.out.println("Image saved at " + target.getAbsolutePath());
            } catch (Exception x) {
                System.err.println("Failed to save Image");
                x.printStackTrace();
            }
        });
        
        saveWrite.setOnAction(e -> {
            try {
                File target = new File("saved_using_write.jpg");
                
                //Convert to bufferedImage
                BufferedImage toWrite = SwingFXUtils.fromFXImage(view.getImage(), null);
                
                //write using ImageIO
                ImageIO.write(toWrite, "jpg", target);
                
                System.out.println("Image saved at " + target.getAbsolutePath());
            } catch (Exception x) {
                System.err.println("Failed to save Image");
                x.printStackTrace();
            }
        });

        root.getChildren().addAll(view, saveCopy, saveWrite);

        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }

}
SDIDSA
  • 894
  • 10
  • 19