Search code examples
javaloopsjarimage-loading

Loading multiple images from source folder when exporting to .jar


I have a program with 3 methods that are used to load images from particular sourced folders. The first one loads a single image given the direct path. The second one loads all images from a folder and stores them in an ArrayList. And the third loads all images from all folders within a folder. (see code below)

When I export to .jar, the first methods works fine. The other 2 methods fail. As far as I understand, it doesn't work because you can't have files in a .jar.

Hence, the code fails here first:

File dir = new File(LoadImages.class.getResource("/" + directory).getFile());

I thought about using FileInputStream instead, but then I can't figure out to to split the stream into parts so that I can assign the images.

The only work around I could think about so far is

public static ArrayList<BufferedImage> loadImageFolder(String directory) {
    ArrayList<BufferedImage> images = new ArrayList<BufferedImage>();
    int i = 0;
    while (true) {
        try {
            BufferedImage img = ImageIO.read(LoadImages.class.getResource("/" + directory + "[" + i + "].png"));
            images.add(img);
            i++;
        } catch (Exception e) {
            break;
        }
    }
    return images;
}

but that forces you to name your files in a certain pattern. Which is possible as you can change the file names before exporting, but I was wondering if there is a way without that.

Thanks in advance.

below the working methods before exporting

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;

import javax.imageio.ImageIO;

public class LoadImages {

    static String extensions = "png";

    static FilenameFilter imageFilter = new FilenameFilter() {

        @Override
        public boolean accept(File dir, String name) {
            if (name.endsWith("." + extensions)) {
                return true;
            }
            return false;
        }
    };

    static FileFilter folderFilter = new FileFilter() {

        @Override
        public boolean accept(File f) {
            if (f.isDirectory()) {
                return true;
            }
            return false;
        }
    };

    public static BufferedImage loadImage(String imageFile) {
        BufferedImage img = null;
        try {
            img = ImageIO.read(LoadImages.class.getResource("/" + imageFile));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return img;
    }

    public static ArrayList<BufferedImage> loadImageFolder(String directory) throws IOException {
        File dir = new File(LoadImages.class.getResource("/" + directory).getFile());
        ArrayList<BufferedImage> images = new ArrayList<BufferedImage>();
        if (dir.isDirectory()) {
            for (File f : dir.listFiles(imageFilter)) {
                BufferedImage img = null;

                try {
                    img = ImageIO.read(f);
                    images.add(img);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    public static ArrayList<ArrayList<BufferedImage>> loadImageFoldersInFolder(String directory) {

        File dir = new File(LoadImages.class.getResource("/" + directory).getFile());
        ArrayList<ArrayList<BufferedImage>> folders = new ArrayList<ArrayList<BufferedImage>>();
        if (dir.isDirectory()) {
            ArrayList<BufferedImage> imagesHere = new ArrayList<BufferedImage>();
            for (File f : dir.listFiles(imageFilter)) {
                BufferedImage img = null;

                try {
                    img = ImageIO.read(f);
                    imagesHere.add(img);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            folders.add(imagesHere);
            for (File f : dir.listFiles(folderFilter)) {
                ArrayList<BufferedImage> folder = new ArrayList<BufferedImage>();
                for (File x : f.listFiles(imageFilter)) {
                    BufferedImage img = null;

                    try {
                        img = ImageIO.read(x);
                        folder.add(img);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                folders.add(folder);
            }
        }
        return folders;
    }

}

Solution

  • Your method doesn't work because you don't have any dircetories in a jar file and not because you can't have files in your jar.

    so in a jar file you have only one level where all your files are. The file names are the path + you`re original filename.

    That's why img = ImageIO.read(LoadImages.class.getResource("/" + imageFile)); works.

    File dir = new File(LoadImages.class.getResource("/" + directory).getFile());
    

    doesn't work because the directory doesn't exist anymore.