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

在很多时候,我们的图像数据往往都不是文件方式存储在磁盘上,而是可能从网络或者数据库中获取的是二进制的图像数据流。最简单的方式和最容易想到的方式就是将这个文件流保存到磁盘上形成一个文件,然后再使用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   王大王  阅读(567)  评论(0编辑  收藏  举报

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示