简体   繁体   中英

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. 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.

I already tested if the InputStream is null as you may have noticed. As it obviously isn't the path to my file has to be right. My question is: Why is ImageIO.read() returning 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):

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. In this case, ImageIO.read(..) will return null .

Just remove that line, and your code should work fine.

The file seems to be present as in is not 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.


If you really need to peek into the bytes in the stream before passing to ImageIO , you could do something like:

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).

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. Remove the call to in.read() , and test the results of the calls.

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. Check for that case as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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