java - 使用 ImageIO 输入 null 异常读取 PNG

标签 java javax.imageio

我正在尝试为我的 Java 类(class)创建一个 Pacman 的基本实现,并且创建了一个测试项目只是为了让该运动正常运行(目前)。我将尝试在面板上移动 JLabel ,并尝试将 JLabel 的图标设置为我已加载到项目中的 PNG 文件。 PNG 文件位于名为 Images 的文件夹中,所有其他类都位于同一项目的 src 文件夹中。当我尝试从我的 src 文件夹类中读取 PNG 文件时,出现以下错误:

Exception in thread "main" java.lang.IllegalArgumentException: input == null!
    at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1400)
    at pacman.<init>(pacman.java:16)
    at screen.<init>(screen.java:9)
    at driver.main(driver.java:6)

driver 创建一个 screen 对象,然后创建一个 pacman 对象,并且错误指向下面的 pacman 类:

import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;

public class pacman {
    Point pacLoc= new Point(0,0);
    Direction pacDir=Direction.RIGHT;
    int pacLives;
    static int count=1;
    int pacID;
    BufferedImage pactest;

    @SuppressWarnings("unused")
    pacman(){
        pacID=count;
        switch(pacID) {
        case 1:
            try {
                pactest=ImageIO.read(getClass().getResource("Images/lolface.png"));
            } catch(IOException a1) {
                a1.printStackTrace();
            }
            pacLoc.setLocation(100,100);
            break;
        case 2:
            try {
                pactest=ImageIO.read(getClass().getResource("Images/whyface.png"));
            } catch(IOException a1) {
                a1.printStackTrace();
            }
            pacLoc.setLocation(100,200);
            break;
        }
        count++;
    }
}

该错误(我认为)源于 ImageIO 找不到 PNG 文件。我是否必须以某种方式将它们导入到我的 pacman 类中?在这种情况下导入语法是什么?我应该提到,我正在使用 Eclipse IDE,并且为了简单起见,我试图避免使用任何外部库。

编辑:

其他 2 个类目前还不是太大,所以如果有帮助的话我也可以将它们发布在这里。

编辑2:

使用 ImageIO.read(pacman.class.getResource("lolface.png")); 而不是 Images/lolface.png 有效。谢谢!

最佳答案

getClass().getResource() 不正确;正确的语法是 pacman.class.getResource(...),其中 pacman 是您自己的类名*。

第二点,你的异常处理被破坏了。异常包含 4 个有用的东西(类型、消息、堆栈跟踪和因果链)。

你扔掉了 4 件东西中的 3 件。不要那样做;要么实际处理它(记录或打印错误处理它!),要么继续抛出它(在方法/构造函数签名上放置throws IOException),或者如果这也不好,请使用catch (Whatever e) { throw new RuntimeException(e); } 这不是很好,但比 e.printStackTrace() 好很多。

您不必导入任何东西; import 是别名类型名称(import com.foo.Bar; 的意思是:任何时候在此文件中的任何位置写入 Bar 并指示类型,想象它读取 com.foo.Bar。它既不会将 Bar 类加载到内存中,也不会在其中运行任何代码,并且与资源无关)。

如果没有错误的堆栈跟踪,我们无法帮助您。

如果case 1开头的行或以case 2开头的行是空指针异常,是的,这是因为找不到资源。

假设您解决了上述问题(pacman.class.getResource 而不是 getClass().getResource),并且这种情况仍然发生:getResource 的工作方式是它看起来相对于包含 pacman.class 的目录...即使所述类位于 jar 文件内。因此,如果您有 /home/BotFred/workspace/com.botfred.pacman/build/com/botfred/pacman/pacman.class,那么它预计图像位于 /home/BotFred/workspace/com.botfred.pacman/build/com/botfred/pacman/Images/lolface.png

如果您不太确定 pacman 类是从哪里加载的,您可以随时执行以下操作来找出答案:

System.out.println(pacman.class.getResource("pacman.class"));

打印结果将类似于 file:///home/BotFred/workspace/com.botfred.pacman/build/com/botfred/pacman/pacman.class 或可能 jar:file:///home/BotFred/pacman.jar!com/foo/botfred/pacman.class (它指示 jar 所在的位置,然后在其中,因为 jar 只是 zip 文件,它会在该位置查找该 jar 的内部) com/foo/botfred/Images/lolface.png 作为您的图像。

*) 原因是 getClass() 根据实例化对象的实际类型,而不是您正在查看的代码。所以,如果你子类化,事情就会崩溃。也许 pacman 目前还没有子类化,但目前的关键字是。也许有一天会是这样。万一突然坏了就惨了。最好从一开始就养成好习惯;始终使用 myclassname.class.getResource ,因为这与您想要实现的目标相匹配(即:使用与此代码所在的类文件存储在同一位置的资源)。

关于java - 使用 ImageIO 输入 null 异常读取 PNG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59023562/

相关文章:

java - 有没有办法在 Spring Boot 应用程序中获取加载的属性文件列表?

java - 为什么在我尝试关闭它们后我的线程仍然处于 Activity 状态?

java - 单击按钮更新 ListView 行项目

java - DateTime ("2019-08-07T19:20-5:00") 转换为具有偏移值的本地日期时间

java - 在java中减少JPG文件的文件大小

java - 为什么 ImageReader 返回不正确的 BufferedImage?

hadoop - 使用ImageIO.write保存图像时出现ArrayIndexOutOfBoundsException

java - 有哪些与 java、spring、hibernate、maven 相关的好博客值得阅读?

java - 如何在java中保存索引颜色PNG

java - ImageIO.write被多线程调用,安全吗?