[英]Java ImageIO.read() returning null
I want to read Images ( .png
files) in my project, and I want this to work in a runnable .jar
file too. 我想在项目中读取图像(
.png
文件),并且我希望它也可以在可运行的.jar
文件中工作。 So I wrote this little piece of code: 所以我写了这段代码:
try {
InputStream in;
in = Loader.class.getClassLoader().getResourceAsStream("buttons.png");
System.out.println(in.read() + ", Reader: " + in);
BufferedImage img = ImageIO.read(in);
System.out.println(img.getHeight());
in.close();
} catch (IOException e) {
e.printStackTrace();
}
When I run it, I get the following output: 运行它时,得到以下输出:
137, Reader: java.io.BufferedInputStream@15db9742
Exception in thread "main" java.lang.NullPointerException
at test.Loader.load(Loader.java:21)
at test.MainTest.main(MainTest.java:6)
My MainTest
does nothing but running this code, so I won't include it here. 我的
MainTest
除了运行此代码外什么也不做,因此在这里不包括它。
I already tested if the InputStream
is null
as you may have noticed. 您可能已经注意到,我已经测试了
InputStream
是否为null
。 As it obviously isn't the path to my file has to be right. 因为显然不是我的文件路径必须正确。 My question is: Why is
ImageIO.read()
returning null
? 我的问题是:为什么
ImageIO.read()
返回null
?
The problem with your code is the line that reads from in
before passing it to ImageIO.read(..)
(you are reading the first byte): 与您的代码的问题是,从读取线
in
它传递给前ImageIO.read(..)
你正在阅读的第一个字节):
System.out.println(in.read() + ", Reader: " + in);
When you read a byte from the stream, this byte is effectively "consumed" and will not be read again, thus ImageIO
will never see this byte, causing the file format (PNG) to not be recognized. 当您从流中读取一个字节时,该字节实际上被“消耗”了,并且不会被再次读取,因此
ImageIO
将永远不会看到此字节,从而导致无法识别文件格式(PNG)。 In this case, ImageIO.read(..)
will return null
. 在这种情况下,
ImageIO.read(..)
将返回null
。
Just remove that line, and your code should work fine. 只需删除该行,您的代码就可以正常工作。
The file seems to be present as in
is not null
. 该文件似乎存在,因为
in
不为null
。 And the value 137
that you print, is actually the first byte of the PNG signature , meaning the file is fine and properly included in your JAR. 而且您输出的值
137
实际上是PNG签名的第一个字节,这意味着该文件很好并且正确包含在JAR中。
If you really need to peek into the bytes in the stream before passing to ImageIO
, you could do something like: 如果确实需要在传递给
ImageIO
之前先查看流中的字节,则可以执行以下操作:
in.mark(256); // allows you to read up to 256 bytes before calling reset()
System.out.println(in.read() + ", Reader: " + in); // or whatever you like to do
in.reset(); // "rewind" to beginning of stream (previous mark)
Just be careful, as not all streams supports mark()/reset()
methods (you can test, using the boolean markSupported()
method). 请注意,因为并非所有流都支持
mark()/reset()
方法(您可以使用boolean markSupported()
方法进行测试)。
As you already read on the InputStream
before the call to ImageIO.read
, it may happens that the function is unable to decode the image correctly. 正如您在调用
ImageIO.read
之前已经在InputStream
上阅读的那样,可能会发生该函数无法正确解码图像的情况。 Remove the call to in.read()
, and test the results of the calls. 删除对
in.read()
的调用,并测试调用结果。
https://docs.oracle.com/javase/8/docs/api/javax/imageio/ImageIO.html#read-javax.imageio.stream.ImageInputStream- https://docs.oracle.com/javase/8/docs/api/javax/imageio/ImageIO.html#read-javax.imageio.stream.ImageInputStream-
ImageIO.read(...)
may return null if it's unable to decode the image. 如果无法解码图像,则
ImageIO.read(...)
可能返回null。 Check for that case as well. 还要检查这种情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.