2009-10-11 3 views
1

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

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

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

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

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

ответ

2

Использование 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 также предоставляет простой итератор каталогов.

+0

Очень полезно. Благодарю. – trikker

1

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

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

0

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

foo_ani = LoadImages("Animations/"); 

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

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

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

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

Учитывая имена файлов, представленных в вопросе, вы не можете просто найти 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 кадров я бы сказал, что это было проще.

Смежные вопросы