Image saved in JavaFX as jpg is pink toned

馋奶兔 提交于 2019-12-04 10:57:00

问题


I want to save an Image from my ImageView to files with different resolutions. Doing it as .png results as expected. As for .jpg - I get all files pink toned.

Where is the trick? Here is the code:

Object[] imagesFromFotoListView = ta.myFotoListView.getItems().toArray();
new File(localDir).mkdirs();
for (int i = 0; i < imagesFromFotoListView.length; i++) {
    new File(localDir + "/" + i).mkdirs(); 
    final ImageView iv = new ImageView((Image) imagesFromFotoListView[i]);
    ImageIO.write(SwingFXUtils.fromFXImage(iv.snapshot(null, null), null), "jpg", new File(localModelFotoDir + "/" + i + "/large.jpg")); // JPG THAT FAILS PINK.
    BufferedImage bi = SwingFXUtils.fromFXImage(iv.snapshot(null, null), null);
    int resolution[] = new int[]{500, 250, 75};
    for (int j = 0; j < resolution.length; j++) {
        BufferedImage resizedBImage;
        if (bi.getWidth() == bi.getHeight()) {
            resizedBImage = resizeBufferedImage(bi, Scalr.Method.ULTRA_QUALITY, Scalr.Mode.AUTOMATIC, resolution[j], resolution[j]);
        } else if (bi.getWidth() > bi.getHeight()) {
            resizedBImage = resizeBufferedImage(bi, Scalr.Method.ULTRA_QUALITY, Scalr.Mode.AUTOMATIC, resolution[j], (int) ((double) resolution[j] * bi.getHeight() / bi.getWidth()));
        } else {
            resizedBImage = resizeBufferedImage(bi, Scalr.Method.ULTRA_QUALITY, Scalr.Mode.AUTOMATIC, (int) ((double) resolution[j] * bi.getWidth() / bi.getHeight()), resolution[j]);
        }
        Image resizedI = (Image) SwingFXUtils.toFXImage(resizedBImage, null);
        ImageIO.write(SwingFXUtils.fromFXImage((Image) SwingFXUtils.toFXImage(resizedBImage, null), null), "png", new File(localModelFotoDir + "/" + i + "/" + resolution[j] + ".png")); // PNG THAT GOES WELL
    }
}

回答1:


I found a solution on Oracle forums. As widely discussed, the problem is in alpha-channel that needs to be excluded from the source image, targeted for .jpg save. I also rearranged my code to make it shorter. The workaround is:

// Get buffered image:
BufferedImage image = SwingFXUtils.fromFXImage(myJavaFXImage, null); 

// Remove alpha-channel from buffered image:
BufferedImage imageRGB = new BufferedImage(
    image.getWidth(), 
    image.getHeight(), 
    BufferedImage.OPAQUE); 

Graphics2D graphics = imageRGB.createGraphics();

graphics.drawImage(image, 0, 0, null);

ImageIO.write(imageRGB, "jpg", new File("/mydir/foto.jpg"));

graphics.dispose();

Fixed in Java 8: https://bugs.openjdk.java.net/browse/JDK-8114609




回答2:


Update

This issue was fixed for Java 8:

JDK-8114609 Incorrect display of JPEG images


It looks like you are encountering existing bugs in the ImageIO or JavaFX Image processing libraries.

  • RT-14647 Incorrect display of JPEG images

You might wish to try some of the workarounds suggested in the StackOverflow questions below and see if any of them fix the issue for you:

  • problem using ImageIO.write jpg file
  • Java 1.5.0_16 corrupted colours when saving jpg image


来源:https://stackoverflow.com/questions/19548363/image-saved-in-javafx-as-jpg-is-pink-toned

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!