Loading all images in a directory.

Started by
6 comments, last by Enigma 17 years, 10 months ago
How would I go about loading all the image files in a directory? Normally I just pass the file name as a string to the image loader. But what if I don’t know the file names, and just want to load everything in a particular directory? This is on WinXP if it matters.
Advertisement
Typically, you can make a call, given a path, and get back some kind of structure that allows you to iterate through all the children of that directory (which are either files or other directories). In Linux, you would look into dirent.h, but I don't think it's the same under windows.
For Windows you can use the FindFirstFile/FindNextFile/FindClose functions to enumerate all files of a directory. You can supply a file mask as well:

void CWinUtils::EnumFilesInDirectory( const char* szFindMask, std::list<std::string>& listFiles, bool bAllowDirectories, bool bClearList ){  WIN32_FIND_DATA   wFindData;  if ( bClearList )  {    listFiles.clear();  }  std::string     strDir = szFindMask;  size_t    iPos = strDir.find_last_of( '\\' );    if ( iPos == std::string::npos )  {    strDir.clear();  }  else  {    strDir = strDir.substr( 0, iPos + 1 );  }  if ( strDir.empty() )  {    char    szTemp[MAX_PATH];    GetCurrentDirectory( MAX_PATH, szTemp );    strDir = szTemp;    if ( ( !strDir.empty() )    &&   ( strDir[strDir.length() - 1] != '\\' ) )    {      strDir += '\\';    }  }  if ( strDir.find_last_of( '\\' ) != std::string::npos )  {    // Add Backslash!    strDir = strDir.substr( 0, strDir.find_last_of( '\\' ) + 1 );  }  HANDLE    hFind = FindFirstFile( szFindMask, &wFindData );  if ( hFind == INVALID_HANDLE_VALUE )  {    return;  }  while ( hFind != INVALID_HANDLE_VALUE )  {    if ( wFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )    {      if ( ( bAllowDirectories )       &&   ( _tcscmp( wFindData.cFileName, _T( "." ) ) )      &&   ( _tcscmp( wFindData.cFileName, _T( ".." ) ) ) )      {        listFiles.push_back( strDir + wFindData.cFileName );      }    }    else    {      listFiles.push_back( strDir + wFindData.cFileName );    }    if ( !FindNextFile( hFind, &wFindData ) )    {      FindClose( hFind );      return;    }  }}

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Take a look at Boost's filesystem library, particularly the directory_iterator class.

Here's an example:

const bool isImageFile(const std::string& fileExtension);void ProcessImageFile(const std::string& filePath);const int ProcessImageFiles(const path& dirPath){  // early-out on bad directory path  if( !exists( dir_path ) || !is_directory(dirPath) )  { return 0;  }  int counter;                // number of image files processed  directory_iterator end_itr; // default construction yields past-the-end  // for each path under dirPath...  for( directory_iterator itr( dirPath ); itr != end_itr; ++itr )  {    // ...if the path isn't a directory, and it is an image file...    if(!is_directory(*itr) && isImageFile(extension(*itr))    {       // ...then process the image file and increment the counter       ProcessImageFile( (*itr).string() );       ++counter;    }  }  return counter;}


PS: Boost's filesystem library is not just pretty - it's also portable.
You never told us what language did you? Anyways, some sort of directory iteration is going to be what you want. Php has a built in DirectoryIterator class (tahts it's name) a c++ example was given. But if you want any sort of cross platform abilities, go with the boost option

cheers
-Dan
When General Patton died after World War 2 he went to the gates of Heaven to talk to St. Peter. The first thing he asked is if there were any Marines in heaven. St. Peter told him no, Marines are too rowdy for heaven. He then asked why Patton wanted to know. Patton told him he was sick of the Marines overshadowing the Army because they did more with less and were all hard-core sons of bitches. St. Peter reassured him there were no Marines so Patton went into Heaven. As he was checking out his new home he rounded a corner and saw someone in Marine Dress Blues. He ran back to St. Peter and yelled "You lied to me! There are Marines in heaven!" St. Peter said "Who him? That's just God. He wishes he were a Marine."
Its C++.

Quote:Original post by ajones
Take a look at Boost's filesystem library, particularly the directory_iterator class.

Here's an example:

*** Source Snippet Removed ***

PS: Boost's filesystem library is not just pretty - it's also portable.


I am trying this now. But I have a few questions. Is the extension function something I have to write my self? Also how does the path work? Is it relative to the exe? If I give it an empty string what happens? And what about subdirectories? Does the directory_iterator recursively go into each or do I have to do that manually?
I am having trouble constructing a new path object. It keeps throwing an execption.

std::string  branch_path = (*itr).branch_path().string();FileName  = branch_path + "/" + basename(*itr) + ".txt";path TextFile(FileName); <-- Gives me an execption why?if(exists(TextFile)/*FileName exists in the curent derectory*/){    ...


I get this message

Unhandled exception at 0x7c81eb33 in Sprite Viewer.exe: Microsoft C++ exception: boost::filesystem::filesystem_error @ 0x0012f908.

And it points my to this code in xstring

bool _Grow(size_type _Newsize,		bool _Trim = false)		{	// ensure buffer is big enough, trim to size if _Trim is true		if (max_size() < _Newsize)			_String_base::_Xlen();	// result too long		if (_Myres < _Newsize)			_Copy(_Newsize, _Mysize);	// reallocate to growExecution point->>	else if (_Trim && _Newsize < _BUF_SIZE)			_Tidy(true,	// copy and deallocate if trimming to small string				_Newsize < _Mysize ? _Newsize : _Mysize);		else if (_Newsize == 0)			_Eos(0);	// new size is zero, just null terminate		return (0 < _Newsize);	// return true only if more work to do		}
You're probably falling foul of portable paths. Try using native name checking.

Σnigma

This topic is closed to new replies.

Advertisement