从缓冲区读取Png图像

时间:2013-12-14 16:16:26

标签: android android-ndk load png assets

我尝试从资产加载PNG,并且我使用AssetManager成功获取它,这是我的功能:

const char* ShaderManager::getPNGSource(const char* src,GLint *length)
{

AAsset* shaderAsset = AAssetManager_open(mgr,src, AASSET_MODE_UNKNOWN);

if (mgr == NULL) {
    LOGE("mgr is null");
}

*length = AAsset_getLength(shaderAsset);

char* buffer = (char*) malloc((*length));

AAsset_read(shaderAsset, buffer, *length);

LOGI("buffer source : %s\n", buffer);

AAsset_close(shaderAsset);

return (buffer);
}

问题是,当我想要解码这个png格式时,我必须使用另一个接受FILE的方法*输入我的函数的开头:

GLuint ShaderManager::png_texture_load(const char * file_name, int * width, int * height)
{
    png_byte header[8];

    FILE *fp = fopen(file_name, "rb");
    if (fp == 0)
    {
        perror(file_name);
        return 0;
    }
    .....
    .....
    .....

这是将o char *转换为FILE *或任何其他解决方案或建议的任何解决方案吗?

3 个答案:

答案 0 :(得分:1)

我想我不能使用AAsset_openFileDescriptor(),因为png是一种压缩格式,关于在文件中写入缓冲区并再次读取它会影响我的游戏的性能吗?

我会考虑如何使用libzip和libpng。

答案 1 :(得分:0)

如果资产未压缩,您可以使用AAsset_openFileDescriptor()

此外,您可以使用fopen fwrite等将缓冲区写入文件。然后你可以从那个文件中读取。您可能需要一个指向您具有读/写访问权限的文件夹的路径。我不确定您是否可以指望当前目录设置为具有读/写访问权限的目录。

答案 2 :(得分:0)

使用funopen打开文件,就像这样。您需要从android_main()中保存AAssetManager *并将其粘贴到全局g_pAssetManager(来自您{android_app} - > activity-> assetManager)。请注意,一旦打开文件,所有正常的fread,fwrite和fclose调用都在_File上工作。

在模块file.h中

struct File{
  FILE* _File;
  AAsset* _A;
  File()
    : _File( nullptr )
    , _A( nullptr )
  {}
  bool open( const char* path, const char* mode );
  void close(){
    fclose( _File );
  }
  bool read( void* buf, size_t size ){
    size_t res = fread( _File, buf, size, 1 );
    if( res == size ){
      return true;
    }
    return false;
  }
};

在模块file.cpp中

extern"C"{
  extern AAssetManager* g_pAssetManager;
}

static int androidRead( void* cookie, char* buf, int size ){
  return AAsset_read( (AAsset*)cookie, buf, size );
}

static int androidWrite( void* cookie, const char* buf, int size ){
  return -1;//can't provide write access to the apk
}

static fpos_t androidSeek( void* cookie, fpos_t offset, int whence ){
  return AAsset_seek( (AAsset*)cookie, offset, whence );
}

static int androidClose( void* cookie ){
  AAsset_close( (AAsset*)cookie );
  return 0;
}

bool File::open( const char* path, const char* mode ){
  if( strchr( mode, 'w' )){
    _File = fopen( path, mode );
    return true;
  }
  _A = AAssetManager_open( g_pAssetManager, path, 0 );
  if( _A ){
    _File = funopen( _A,
      androidRead,
      androidWrite,
      androidSeek,
      androidClose );
    }
    if( _File != nullptr ){
      return true;
    }
  }
  return false;
}