Чтение в графических файлах без указания имени - PullRequest
1 голос
/ 11 октября 2009

Существуют ли какие-либо средства в SDL или C ++, которые позволяют считывать файлы изображений из папки без указания их имени, например, читать их в последовательном порядке и т. Д.? Если нет, то есть ли какие-либо методы, которые вы используете для достижения чего-либо в том же духе? ​​

Делать что-то вроде этого:

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

может стать довольно утомительным, и цикл не может быть использован, потому что имя файла является конкретным каждый раз.

Единственный способ, о котором я мог бы подумать, это, возможно, иметь строку, которую вы изменяете в каждом итераторе цикла и вставляете номер цикла в определенную часть строки, предполагая, что именно так помечены ваши файлы, и используя эту строку в качестве LoadImage. параметр. Это похоже на большую работу, чем просто выполнение вышеизложенного.

Ответы [ 4 ]

2 голосов
/ 11 октября 2009

Использование boost::filesystem.

Крошечная программа, показанная здесь, перечисляет все файлы в каталоге files/, соответствующие шаблону fileN.type, где N от 0 и выше, не указано.

#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;
}

Связь с -lboost_filesystem.

boost::filesystem также предоставляет простой итератор каталога.

1 голос
/ 11 октября 2009

Для ситуаций такого типа вы обычно получаете список имен файлов в каталоге (с opendir / readdir или FindFirstFile / FindNextFile в зависимости от обстоятельств) и цикл для каждого имени файла в каталоге. Для каждого имени файла вы можете вызвать LoadImage() и добавить результат в ваш массив.

Этот метод не требует, чтобы вы знали имена файлов заранее.

0 голосов
/ 12 октября 2009

Учитывая, что вы в настоящее время жестко кодируете имя фреймов, я предполагаю, что вы знаете / имеете контроль над схемой именования файлов. Я также предполагаю, что вы хотите их последовательно, так как это кажется кадрами в анимации. Наконец, я предполагаю, что вы знаете, сколько существует кадров, так как у вас, кажется, есть массив, достаточно большой, чтобы вместить их всех, готовых и ожидающих.

Учитывая имена файлов, представленных в вопросе, вы не можете просто выполнить FindFirst / FindNext, потому что как только вы пройдете 10 кадров, они почти наверняка выйдут из строя (учитывая представленную схему именования) .

Так что я думаю, что вы правы, что лучший способ сделать это в цикле, но неправильно, что это больше усилий, чем делать это вручную.

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;

Это примерно 6 строк кода. Так что для анимации из более чем 6 кадров я бы сказал, что это проще.

0 голосов
/ 11 октября 2009

Как насчет автоматической загрузки всех файлов в этом каталоге?

foo_ani = LoadImages("Animations/");

Просто пройдите по указанному каталогу и загрузите все файлы внутри него.

Другое решение, если у вас есть несколько анимаций с разными префиксами, это использование регулярных выражений. Я предлагаю вам использовать boost для этого или std::tr1::regex, например:

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