使用 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();
我以最小的形式重现了这个问题:
主线:
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();