簡體   English   中英

Java ImageIO.read()返回null

[英]Java ImageIO.read() returning null

我想在項目中讀取圖像( .png文件),並且我希望它也可以在可運行的.jar文件中工作。 所以我寫了這段代碼:

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();
}

運行它時,得到以下輸出:

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)

我的MainTest除了運行此代碼外什么也不做,因此在這里不包括它。

您可能已經注意到,我已經測試了InputStream是否為null 因為顯然不是我的文件路徑必須正確。 我的問題是:為什么ImageIO.read()返回null

與您的代碼的問題是,從讀取線in它傳遞給前ImageIO.read(..)你正在閱讀的第一個字節):

System.out.println(in.read() + ", Reader: " + in);

當您從流中讀取一個字節時,該字節實際上被“消耗”了,並且不會被再次讀取,因此ImageIO將永遠不會看到此字節,從而導致無法識別文件格式(PNG)。 在這種情況下, ImageIO.read(..)將返回null

只需刪除該行,您的代碼就可以正常工作。

該文件似乎存在,因為in不為null 而且您輸出的值137實際上是PNG簽名的第一個字節,這意味着該文件很好並且正確包含在JAR中。


如果確實需要在傳遞給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)

請注意,因為並非所有流都支持mark()/reset()方法(您可以使用boolean markSupported()方法進行測試)。

正如您在調用ImageIO.read之前已經在InputStream上閱讀的那樣,可能會發生該函數無法正確解碼圖像的情況。 刪除對in.read()的調用,並測試調用結果。

https://docs.oracle.com/javase/8/docs/api/javax/imageio/ImageIO.html#read-javax.imageio.stream.ImageInputStream-

如果無法解碼圖像,則ImageIO.read(...)可能返回null。 還要檢查這種情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM