使用 ImageIO.write 写入 jpg 或 jpeg 图像不会创建图像文件

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

我以最小的形式重现了这个问题:

主线:

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

重要提示:我正在使用 JavaFX 12。

如果我将图像导出为 png,该图像会显示在我的桌面上。例如,如果文件格式为 jpeg,则不会创建图像。

过去,当我使用 JavaFX 8 另存为 jpeg 时,使用上述代码导致图像变成粉红色调。现在在版本 12 中没有任何反应。

那么如何创建格式不是 png 而是 jpeg 格式的图像?

我还检查了 ImageIO 支持的格式,returns 这些格式:

JPG, jpg, tiff, bmp, BMP, gif, GIF, WBMP, png, PNG, JPEG, tif, TIF, TIFF, wbmp, jpeg

首先,我可以确认 JavaFX 13 ea build 13 的这种行为。这可能是修复 OP 已经提到的旧错误(图像变成粉红色)的非常简单的尝试,我很久以前就报告过.问题在于 JPEGS 无法存储 alpha 信息,并且在过去,当将具有 alpha 通道的图像写为 JPEG 时,输出只是乱码。该修复程序现在完全拒绝写出图像,而不仅仅是忽略 alpha 通道。

解决方法是复制您在其中明确指定没有 alpha 通道的颜色模型的图像。

这是包含解决方法的原始错误报告:https://bugs.openjdk.java.net/browse/JDK-8119048

以下是一些用于简化转换的更多信息: 如果您将此行添加到您的代码

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

然后用这个作为第二个参数而不是 null 调用 SwingFXUtils.fromFXImage(img, awtImage),然后将自动完成所需的转换并按预期写入 JPEG。

除了 mipa 的答案之外,如果您没有可用的 SwingFXUtils,您可以将 BufferedImage 克隆到另一个没有 alpha 通道的 BufferedImage:

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