BufferedImage to JavaFX image

37,576

Solution 1

You can use

Image image = SwingFXUtils.toFXImage(capture, null);

Solution 2

normally the best choice is Image image = SwingFXUtils.toFXImage(capture, null); in java9 or bigger.... but in matter of performance in javafx, also in devices with low performance, you can use this technique that will do the magic, tested in java8

private static Image convertToFxImage(BufferedImage image) {
    WritableImage wr = null;
    if (image != null) {
        wr = new WritableImage(image.getWidth(), image.getHeight());
        PixelWriter pw = wr.getPixelWriter();
        for (int x = 0; x < image.getWidth(); x++) {
            for (int y = 0; y < image.getHeight(); y++) {
                pw.setArgb(x, y, image.getRGB(x, y));
            }
        }
    }

    return new ImageView(wr).getImage();
}
Share:
37,576
Nanor
Author by

Nanor

Updated on August 19, 2020

Comments

  • Nanor
    Nanor over 3 years

    I have an image I screenshot from the primary monitor and I want to add it to a Java FX ImageView as so:

    @FXML
    protected ImageView screenshot() throws AWTException, IOException {
        Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
        BufferedImage capture = new Robot().createScreenCapture(screenRect);
        ImageView imageView = new ImageView();
        Image image = capture; //Error
        imageView.setImage(image);
        return imageView;
    }
    

    I'm trying to set the BufferedImage capture to javafx.scene.image.Image image but the types are incompatible nor am I able to cast it. How can I rectify this?

  • Halil
    Halil about 7 years
    Can you comment about the performance of this solution? Is there a way to directly create javafx.scene.image.Image without first creating BufferedImage?
  • Erik Stens
    Erik Stens almost 5 years
    I had the exact same question when I got here. I looked in the implementation of SwingFXUtils and saw it's indeed possible if you create a JavaFX WritableImage. In that case you can get its PixelWriter and just write a data buffer to the image. This is very fast and similar to what you'd do with a BufferedImage. I got very good performance out of this.
  • mipa
    mipa over 4 years
    What kind of magic is that? For me this looks like the slowest possible solution to copy over any single pixel individually.
  • Dan
    Dan over 4 years
    looks like that but beleive me, it works fast, I test it in Raspian devices (slow performance also in a slow internet) and in both windos a linux (ubuntu), the behavior was the same (always using javafx from jre1.8). I needed to find another solution and this is what I found. use the soltion that best suits you
  • Nighty42
    Nighty42 almost 4 years
    You can skip the creation of the BufferedImage if you just want to convert a byte[] to a JavaFX image - see the comment of the user "FinalArt2005" under the best answer.