Search code examples
javaimageimage-processingstb-image

Java Images/STB Images: peek into file to check width/height without actually loading the whole image (checking image metadata?)


I'm making a texture streaming system for my game. I've successfully built it - but it has one problem. For the first frame after it's made, the width/height is 1 because it has begun being read yet by the streamer. I'm trying to think of a way I can possibly "peek" into the image's file and get the dimensions without actually loading the whole thing at once.

I have a few limitations here: we don't use AWT and can't access it. Due to how our threads are set up (due to making it compatible with MacOS), if we try and access AWT, it'll crash the program on Mac Systems. So I can't use any of those tools (BufferedImage, etc). I've never accessed ImageIO before either, but I'm quite sure if it'd cause a crash just because it has a function that returns BufferedImages.

What I have access to is the file location itself. The first thing that comes to mind is checking the image metadata, and at the very least using that as a placeholder. When I've checked online, it appears that the only native to Java method is using ImageIO, but as I said above, I think that could cause crashes due to it referencing AWT classes for stuff like ImageIO read.

So, to summarize: I'm streaming a texture, but I need a way to check the image for its dimensions (without actually loading the entire image) so that I know the dimensions immediately/as soon as the streaming is set up.

Thank you!

Edit* I also forgot to mention, we use Java-bindings for STB-Image for our texture loading/saving/etc needs. If it has a way to access metadata, please let me know!


Solution

  • I figured it out. Keep in mind that I'm using STBImage on the LWJGL bindings, but:

        try (MemoryStack stack = MemoryStack.stackPush()) {
            IntBuffer w = stack.mallocInt(1);
            IntBuffer h = stack.mallocInt(1);
            IntBuffer c = stack.mallocInt(1);
            
            STBImage.stbi_info(imageFile.getAbsolutePath(), w, h, c);
            
            return new Vector2i(w.get(), h.get());
        }
    

    This will check the given file's image dimensions without actually fully loading it. It outputs a Vector2i containing the dimensions.