简体   繁体   English

Java ImageIO.read()返回null

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM