ネイティブ側からアセットフォルダー内の画像ファイルにアクセスしようとしています。これで、アセットフォルダーとそのサブディレクトリを検索して、探している特定のファイルを見つけることができます。
AAssetDir* assetDir = AAssetManager_openDir(asset_manager, "images");
const char* filename;
while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL)
{
__Android_log_print(Android_LOG_DEBUG, "Debug", filename);
}
AAssetDir_close(assetDir);
OSGも使用しています。次のコードを使用して、イメージをシェーダーのテクスチャとして設定します。
texture->setImage(osgDB::readImageFile(fileNameWithPath));
ただし、同じディレクトリにないため、そのファイル名には絶対パスも含める必要があります。ただし、アセットディレクトリの絶対パスを取得できないことがわかりました。APKとともに圧縮されているためです。
絶対パスにアクセスできないので、画像を取得する他の方法はありますか?また、注意してください、私は、sdカードへの提案として、資産フォルダにファイルを保持したいと思います。
AAssetManager_open
&AAsset_read
を使用してアセットから画像を読み取ることができますが、アセットがapkにあるため、そのファイルパス名を取得できません-また、そこで圧縮されます。データをファイルに保存し、後でそのファイルから読み取ることも、OSGで許可されている場合はアセットファイルから取得したチャンクを直接処理することもできます。
ここ から:
AAssetDir* assetDir = AAssetManager_openDir(mgr, "");
const char* filename = (const char*)NULL;
while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) {
AAsset* asset = AAssetManager_open(mgr, filename, AASSET_MODE_STREAMING);
char buf[BUFSIZ];
int nb_read = 0;
FILE* out = fopen(filename, "w");
while ((nb_read = AAsset_read(asset, buf, BUFSIZ)) > 0)
fwrite(buf, nb_read, 1, out);
fclose(out);
AAsset_close(asset);
}
AAssetDir_close(assetDir);
言及する価値のあるもう1つのことは、Androidは、一度に読み取ることができるアセットサイズを1Mbに制限します。ファイルがそれより大きい場合は、チャンクに分割する必要があります。チャンクのファイルを文字のベクトルにロードする私の作業ソリューションです:
AAssetManager * mgr = app->activity->assetManager;
AAssetDir* assetDir = AAssetManager_openDir(mgr, "");
const char* filename;
std::vector<char> buffer;
while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL)
{
//search for desired file
if(!strcmp(filename, /* searched file name */))
{
AAsset *asset = AAssetManager_open(mgr, filename, AASSET_MODE_STREAMING);
//holds size of searched file
off64_t length = AAsset_getLength64(asset);
//keeps track of remaining bytes to read
off64_t remaining = AAsset_getRemainingLength64(asset);
size_t Mb = 1000 *1024; // 1Mb is maximum chunk size for compressed assets
size_t currChunk;
buffer.reserve(length);
//while we have still some data to read
while (remaining != 0)
{
//set proper size for our next chunk
if(remaining >= Mb)
{
currChunk = Mb;
}
else
{
currChunk = remaining;
}
char chunk[currChunk];
//read data chunk
if(AAsset_read(asset, chunk, currChunk) > 0) // returns less than 0 on error
{
//and append it to our vector
buffer.insert(buffer.end(),chunk, chunk + currChunk);
remaining = AAsset_getRemainingLength64(asset);
}
}
AAsset_close(asset);
}
}