Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing jpg or jpeg image with ImageIO.write does not create image file

I recreated the issue in a minimal form:

MAIN:

public class ImageIOMain extends Application {

    @Override
    public void start(Stage stage) throws Exception{
        Scene scene = new Scene(new StackPane(), 800.0, 600.0);

        stage.setScene(scene);
        stage.show();

        WritableImage img = scene.snapshot(null);

        //Image file created on desktop
        ImageIO.write(SwingFXUtils.fromFXImage(img, null), "png", new File("D:\\Desktop\\test.png"));

        //Image file NOT created on desktop
        ImageIO.write(SwingFXUtils.fromFXImage(img, null), "jpeg", new File("D:\\Desktop\\test.jpeg"));
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Important: I'm using JavaFX 12.

If I export an image as png the image shows up on my desktop. If the file format is for example jpeg then the image is not created.

In the past when I used JavaFX 8 saving as jpeg using the above code caused the image to became pink toned. Now in version 12 nothing happens.

So how can I create an image which format is not png but something else like jpeg?

I also checked ImageIO supported formats which returns these:

JPG, jpg, tiff, bmp, BMP, gif, GIF, WBMP, png, PNG, JPEG, tif, TIF, TIFF, wbmp, jpeg
like image 852
Ricky Avatar asked Aug 27 '19 10:08

Ricky


2 Answers

Additionally to the answer of mipa and in the case that you do not have SwingFXUtils available, you could clone the BufferedImage into another BufferedImage without alpha channel:

BufferedImage withoutAlpha = new BufferedImage(
    (int) originalWithAlpha.getWidth(),
    (int) originalWithAlpha.getHeight(), 
    BufferedImage.TYPE_INT_RGB);
Graphics g = withoutAlpha.getGraphics();
g.drawImage(originalWithAlpha, 0, 0, null);
g.dispose();
like image 38
S. Doe Avatar answered Oct 17 '22 12:10

S. Doe


First of all I can confirm this behaviour for JavaFX 13 ea build 13. This was probably a very simplistic attempt to fix an old bug which the OP has already mentioned (image turning pink) which I reported a long time ago. The problem is that JPEGS cannot store alpha information and in the past the output was just garbled when an image with an alpha channel was written out as a JPEG. The fix now just refuses to write out the image at all instead of just ignoring the alpha channel.

A workaround is to make a copy of the image where you explicitly specify a color model without alpha channel.

Here is the original bug report which also contains the workaround: https://bugs.openjdk.java.net/browse/JDK-8119048

Here is some more info to simplify the conversion: If you add this line to your code

BufferedImage awtImage = new BufferedImage((int)img.getWidth(), (int)img.getHeight(), BufferedImage.TYPE_INT_RGB);

and then call SwingFXUtils.fromFXImage(img, awtImage) with this as the second parameter instead of null, then the required conversion will be done automatically and the JPEG is written as expected.

like image 103
mipa Avatar answered Oct 17 '22 12:10

mipa