buffereimage在运行时为Null



我在运行时遇到BufferedImage的问题。我正在加载。png文件,但buffereimage是空的。我没有得到IOException,而是NullPointerException。对我来说最大的问题是,当我在netbeans中运行相同的代码时,他工作得很好…

我的代码是
public Image loadImage() throws IOException {
BufferedImage bufferedImage = ImageIO.read(new File(ApplicationProperties.getPath() + "\.wimdesktop\image.png"));
return SwingFXUtils.toFXImage(bufferedImage, null);
}

ApplicationProperties.getPath()是静态的,在运行时不会改变。如果我分开BufferedImage的声明并尝试file.exists()我得到一个真实的结果

好吧,阅读文档。当然,这是一种奇怪的行为,但文档会为您详细说明:

返回一个buffereimage作为解码提供的文件的结果,其中ImageReader从当前注册的文件中自动选择。文件被包装在一个ImageInputStream中。如果没有注册的ImageReader声明能够读取结果流,则返回null.

(我添加了高亮)。换句话说,这是一种有意的行为。

这个方法不好,你不应该调用它。打电话给其他的人,夺回控制权。通常,这样的图像和你的类文件一样是静态的:你在创建这个程序的时候决定这些图像应该是什么样子,你的用户不应该制作它们,编辑它们,或者对它有任何影响。因此,将这些图像存储在与"存储"类文件相同的地方是有意义的:在jar或jmod中,一起。

你可以要求java从它读取类文件的相同位置读取内容。我觉得你应该用这个机制。你需要一个方法,需要一个InputStreamURL。幸运的是,这两种方法都有read方法的重载。因此:

  • 如果你有一个java文件MyApp.java,它开始与package com.foo;,那么你最终有一个jar文件,其中包含条目com/foo/MyApp.class;如果你运行jar tvf myapp.jar,你可以看到这个
  • 现在确保映像位于相同的jar中,可以在com/foo的子目录中,也可以在jar的根目录中,由您选择。假设你有com/foo/img/image.png在这个jar中。

然后,创建一个buffereimage:

BufferedImage img = ImageIO.read(MyApp.class.getResource("img/image.png"));
return SwingFXUtils.toFXImage(img, null);

如果你因为一些奇怪的原因必须离开一个文件,控制这个进程以获得非愚蠢的错误处理(不幸的是,接受file的read方法被认为是愚蠢的错误处理,所以你不想要那个):

try (FileInputStream in = new FileInputStream(new File(...))) {
BufferedImage img = ImageIO.read(in);
}

这样,如果img现在是null,你知道这个文件很可能被读取了,但它要么不是一个有效的图像,要么是java无法读取的格式(例如,我不认为java可以保证读取任何东西,除了png和jpg。所以它可能是HEIF/HEVC, TIFF, BMP等-据我所知java将无法读取的东西)。

与您所做的相反,也可能是该文件不存在或您的java进程没有对该文件的读访问权限。

相关内容

最新更新