Automatically loading image assets in exported application

edited February 2016 in Questions about Code

I am using Processing 3.0.1 (REV 0247) in Eclipse. I have the following code that automatically loads all image assets that are stored in my data folder:

private HashMap<String, PImage> imageCache = new HashMap<String, PImage>();

File[] files = new File( "bin\\data" ).listFiles();

if ( files == null ) {
    throw new Exception( "Error loading assets." );
}

for ( File file : files ) {
    String path = file.getAbsolutePath();     
    if ( path.toLowerCase().endsWith( ".jpg" ) || path.toLowerCase().endsWith( ".png" ) || path.toLowerCase().endsWith( ".gif" ) || path.toLowerCase().endsWith( ".tga" ) ) {
        imageCache.put( file.getName(), loadImage( path ) );
    }
}

It works correctly when I run the application via Eclipse, but if I export the project into a runnable JAR file, the "bin\\data" file path will not work.

I've tried playing around with all of these functions but with with no success:

sketchPath()
sketchPath( "data" )
sketchOutputPath()
dataFile( "" )
dataPath( "" )

Most of these point to \lib\base which does not contain any of my image files. Does anyone know how I can fetch a file path that will essentially look into bin\\data when using Eclipse and simply the data folder when in an exported build?

Answers

  • edited February 2016

    Don't got Eclipse but, if I export this sketch w/ CTRL+SHIFT+E from Processing's PDE, it still works: ~O)

    // forum.Processing.org/two/discussion/14821/
    // automatically-loading-image-assets-in-exported-application
    
    // GoToLoop (2016-Feb-08)
    
    size(800, 150);
    smooth(4);
    noLoop();
    
    background(0);
    fill(#FFFF00);
    
    textSize(020);
    textAlign(CENTER, CENTER);
    
    String path = dataFile("").getPath();
    text(path, width>>1, height>>1);
    
  • edited February 2016

    So for me, dataFile("").getPath(); points to ...\lib\base\data. My base folder contains the following:

    iMlWiAJ

    Which has no data folder. Currently, I'm copying my assets into ...\src\data, which Eclipse automatically duplicates into ...\bin\data. Is there any way I can consistently point to one of those folders when building in Eclipse, and point to just \data when exported into a JAR?

    Thanks for the help!

  • Both dataPath() & dataFile() are based on system variable sketchFolder.
    And sketchFolder points to the folder where the sketch is run from. ^#(^

  • Answer ✓

    So this is somewhat ugly, but here's the solution that I ended up with:

    private HashMap<String, PImage> imageCache = new HashMap<String, PImage>();
    
    private void loadAssets() throws Exception
    {
    File[] files = new File( "bin\\data" ).listFiles();
    
    if ( files == null )
    {
        files = new File( "data" ).listFiles();
    
        if ( files == null )
        {
        throw new Exception( "Error loading assets." );
        }
    }
    
    for ( File file : files )
    {
        String path = file.getAbsolutePath();
    
        if ( path.toLowerCase().endsWith( ".jpg" ) || path.toLowerCase().endsWith( ".png" ) || path.toLowerCase().endsWith( ".gif" ) || path.toLowerCase().endsWith( ".tga" ) )
        {
        imageCache.put( file.getName(), loadImage( path ) );
        }
    }
    }
    

    Seems to work for my means. Tried all of the different file path methods provided by Processing and couldn't find anything more reliable to use.

  • Also, just in case someone digs this post up later down the road (like many in the past that I have), the main idea behind this method is to automatically load/cache any images in the data folder, and then a behavior that needs to access an image can just fetch it once from the HashMap by file name. Would not recommend repeatedly accessing it in the HashMap though, store a reference instead.

  • Answer ✓

    False alarm. That didn't actually work for the exported version. Just using this instead...

    public PImage getCachedImage( String fileName ) throws Exception
    {
    PImage image = imageCache.get( fileName );
    
    if ( image == null )
    {
        image = loadImage( fileName );
        imageCache.put( fileName, image );
    }
    
    return image;
    }
    

    Thanks for the help, GoToLoop. Much appreciated. And sorry, I can't seem to figure out how to do proper code block snippets w/ this form of Markdown.

Sign In or Register to comment.