Trying to load image using ImageIO.read(class.getR

2019-01-20 12:24发布

问题:

I've been making a 2D game with my buddy and I've been learning a lot about some basic game dev concepts through some Youtube tutorials. One of the things I was learning about is sprites (for those that don't know, 2D images to render to the screen) and how to use them in my game. I've been using ImageIO.read(this.class.getResource(pathToMySprite)) but it seems that getResource() is returning null for some reason.

I've been screwing around with the path a little, adding "/" in front of it, removing "/", putting the user.dir property to see if it needed the whole path, and I'm still getting the same error.

TILE_TEXTURES(System.getProperty("user.dir") + "/textures/tile.png");
//ENTITY_TEXTURES("/textures/entity.png");
private BufferedImage img;

private SpriteSheet(String path) {

System.out.println(System.getProperty("user.dir"));
try {
   //TODO: Fix this error, don't know what's wrong.
     img = ImageIO.read(SpriteSheet.class.getResource(path)); // error here!!!
    } catch (IOException e) {
      e.printStackTrace();
    }
 }

public BufferedImage getImage() {
        return img;
}

Any and all help is appreciated. I haven't been commenting the code (I usually do that when I get to place where I can sit back and be happy with what I've finished) but it's a pretty small class so I think you guys will be able to understand what's going on just fine.

The folder that holds the image IS in the class path of my project. I've also included the error:

Exception in thread "Thread-2" java.lang.ExceptionInInitializerError
    at com.brickbattle.client.src.gui.Sprite.<clinit>(Sprite.java:7)
    at com.brickbattle.client.src.objs.Tile.<init>(Tile.java:67)
    at com.brickbattle.client.src.objs.Player.initPlayerNum(Player.java:19)
    at com.brickbattle.client.src.util.BrickBattle.init(BrickBattle.java:114)
    at com.brickbattle.client.src.util.BrickBattle.run(BrickBattle.java:85)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: input == null! //HERE IS ERROR
    at javax.imageio.ImageIO.read(Unknown Source)
    at com.brickbattle.client.src.gui.SpriteSheet.<init>(SpriteSheet.java:17)
at com.brickbattle.client.src.gui.SpriteSheet.<clinit>(SpriteSheet.java:8)

Thanks again!

回答1:

This problem is basically unrelated to ImageIO, but rather how Class/ClassLoader.getResource or getResourceAsStream works.

For an explanation, see this answer.

In any case, these ways of obtaining a resource will only be able to read from classpath (ie. user.dir will never help here).

This should work:

ImageIO.read(getClass().getResource("/path/to/resource"));

Where the path is relative to the root of the classpath (specified by the leading /).

If your resources are not on the classpath, simply use:

ImageIO.read(new File("path/to/resource");

Where the path is relative to the directory your application was launched from.