【问题标题】:Writing jpg or jpeg image with ImageIO.write does not create image file使用 ImageIO.write 写入 jpg 或 jpeg 图像不会创建图像文件
【发布时间】:2019-08-27 10:47:46
【问题描述】:

我以最小的形式重新创建了问题:

主要:

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 支持的格式,这些格式返回:

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

【问题讨论】:

  • 您能否编辑您的问题并发布您正在使用的 VM 参数(即--add-modules)或您的 build.gradle/pom.xml 文件?
  • hmm ... 确实调试到 JPEGImageWriterSpi.canEncode: 返回 false 因为 ColorModel 有一个 alpha 值 .. 对图像编码知之甚少,但是

标签: javafx jpeg javax.imageio


【解决方案1】:

首先,我可以确认 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);

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 这个答案解决了问题,现在将图像写入文件,但现在我通常的白色背景是黑色的。
    • 使用带有 Color 参数的其他 Graphics.drawImage 方法之一。请参阅文档:“bgcolor 在图像的非透明部分下绘制的背景颜色。”试试 Color.WHITE。
    • 我做了,但我的图像的背景似乎是透明黑色,所以它仍然是黑色,我需要手动将透明黑色更改为不透明白色。
    猜你喜欢
    • 2022-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-18
    • 1970-01-01
    • 2012-08-20
    • 2012-05-18
    相关资源
    最近更新 更多