在非常多时候。我们的图像数据往往都不是文件方式存储在磁盘上。而是可能从网络或者数据库中获取的是二进制的图像数据流。最简单的方式和最easy想到的方式就是将这个文件流保存到磁盘上形成一个文件,然后再使用GDAL来打开进行处理。
可是这样有一个不太好的地方就是须要生成一个磁盘的暂时文件。并且在磁盘上折腾了一圈后会添加不必要的系统开销。
针对这个文件。GDAL库里面已经有现成的API来进行处理。以下就使用一个简单的样例来进行说明,代码例如以下:
GByte *GetStream(const char* pszFile, int &nSize)
{
FILE* pFile = fopen(pszFile, "rb");
fseek(pFile, 0, SEEK_END);
nSize = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
GByte *pBuffer = new GByte[nSize];
fread(pBuffer, nSize, 1, pFile);
fclose(pFile);
return pBuffer;
}
int StreamTest()
{
//为了測试,从一个文件里将所有的数据读取为二进制流
const char* pszFile = "F:\\Data\\Test.tif";
// 为了构造内存文件。必须有一个内存文件名,以/vsimem/开头。后面的随便啥都行。
// 这里使用00000000这个来进行測试
string osMemFileName = "/vsimem/00000000";
// 写了一个函数。读取二进制数据,也能够从数据库中或者网络啥的获取图像的二进制流存储在pabyData中
int nDataSize = 0;
GByte* pabyData = GetStream(pszFile, nDataSize);
// 将二进制流构造到MEM文件里
VSIFCloseL(VSIFileFromMemBuffer( osMemFileName.c_str(), pabyData, nDataSize, FALSE));
GDALAllRegister();
// 使用GDALOpen打开构造好的MEM文件
GDALDatasetH hDS = GDALOpen(osMemFileName.c_str(), GA_ReadOnly);
if (hDS == NULL)
{
// 打开失败。将内存文件进行释放
VSIUnlink(osMemFileName.c_str());
return FALSE;
}
// 以下就依照正常的图像处理流程处理就可以
printf("width = %d\nheight = %d\n", GDALGetRasterXSize(hDS), GDALGetRasterYSize(hDS));
// 关闭图像
GDALClose(hDS);
// 处理结束后,将内存文件进行释放
VSIUnlink(osMemFileName.c_str());
delete [] pabyData;
return TRUE;
}
上面GetStream函数用来读取一个数据流。具体的注视都在代码里面了。