tags:

views:

69

answers:

4

Are there any facilities in SDL or C++ that allow you to read image files in from a folder without specifying their name, like reading them in sequential order, etc.? If not are there any techniques you use to accomplish something along the same lines?

Doing something like this:

foo_ani[0] = LoadImage("Animations/foo1.png");
foo_ani[1] = LoadImage("Animations/foo2.png");
foo_ani[2] = LoadImage("Animations/foo3.png");

can become quite tedious, and a loop can't be used because the file name is specific each time.

The only way I could really think of is maybe having a string that you modify through each loop iterator and insert the loop number into the specific part of the string assuming that's how your files are labeled, and using that string as the LoadImage parameter. That seems like more work though than just doing the above.

+1  A: 

For this type of situation, you would typically get a list of the filenames in the directory (with opendir/readdir or FindFirstFile/FindNextFile as appropriate), and loop on each filename in the directory. Given each filename, you can call LoadImage() and append the result to your array.

This technique doesn't require that you know the filenames ahead of time.

Greg Hewgill
A: 

How about loading all files in that directory automatically?

foo_ani = LoadImages("Animations/");

Just traverse the directory given and load all files inside that fit.

Another solution, if you have several animations with different prefix is to use regular expressions. I suggest you use boost for that or std::tr1::regex, like this:

foo_ani = LoadImageSet("Animations/", std::tr1::regex("foo*.png"));
LiraNuna
+2  A: 

Use boost::filesystem.

The tiny program shown here lists all files in the directory files/, matching the pattern fileN.type, where N is from 0 and upwards, unspecified.

#include <iostream>
#include <sstream>
#include <string>
#include <boost/filesystem.hpp>

using namespace std;
namespace fs = boost::filesystem;
int main(int argc, char** argv)
{
    fs::path dir ("./files");
    string prefix = "file";
    string suffix = "type";
    int i = 0;

    fs::path file;

    do {
     stringstream ss;
     ss << prefix << i++ << "." << suffix;
     file = fs::path(dir / fs::path(ss.str()));
     if(fs::exists(file)) {
      cout << file.leaf() << " exists." << endl;
     }
    } while(fs::exists(file));
    return 0;
}

Link with -lboost_filesystem.

boost::filesystem also provides a simple directory iterator.

gnud
Very helpful. Thanks.
trikker
A: 

Given that you are are currently hard coding the name of the frames, I'm going to assume you know / have control over the naming scheme of the files. I'm also assuming you want them sequentially since it seems to be frames in an animation. Finally I'm assuming you know how many frames there are since you seem to have an array big enough to accommodate them all ready and waiting.

Given the names of the files presented in the question, you can't just do FindFirst / FindNext because once you get past 10 frames, they're almost certainly going to come in out of order (given the naming scheme presented).

So I think that you're right that the best way to do it is in a loop, but wrong that it's more effort than doing it by hand.

char* fname = new char[50]; // buffer big enough to hold filenames
int numFrames = 8; // or however many, you seem to know what this value should be

for(int i = 0; i < numFrames;  ++i)
{
    sprint(fname, "Animations/foo%d.png",(i+1));
    foo_ani[i] = LoadImage(fname);
}

delete[] fname;

That's about 6 lines of code. So for animations of more than 6 frames, I'd say that was easier.

Gareth Simpson