从二进制数据流中构造GDAL能够读取的图像数据

在非常多时候。我们的图像数据往往都不是文件方式存储在磁盘上。而是可能从网络或者数据库中获取的是二进制的图像数据流。最简单的方式和最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函数用来读取一个数据流。具体的注视都在代码里面了。

posted on 2017-07-06 21:09  ljbguanli  阅读(272)  评论(0编辑  收藏  举报