利用GDAL從內存中直接解析圖像數據


對於網絡數據源,調度中可以把數據寫入本地,然后讀取本地數據格式進行影像的解析(地形有時候也用tif等格式)。

此種方式會每次調度進行不必要的IO開銷和時間花費。

 

GDAL提供了相應的接口,直接從內存中解析數據,避免了磁盤寫入和讀取操作。具體步驟是:

(1)利用內存中的二進制數據流創建對應的內存文件  即 從 Buffer 創建  memory "file",這里的內存文件路徑是位於GDAL自定義的虛擬文件目錄 /vsimem/下。

(2)和解析本地文件一樣,利用GDALOpen 讀取內存文件。

//通過讀取本地文件,產生二進制數據流 buffer、size
	FILE* pFile = fopen("D:\\data\\1.tif","rb");
	fseek(pFile,0,SEEK_END);
	int size = ftell(pFile);
	rewind(pFile);

	GByte * buffer  = new GByte [size];
	fread(buffer,1,size,pFile);
	fclose(pFile);

	//利用二進制流創建內存文件
	VSIFCloseL(VSIFileFromMemBuffer("/vsimem/work",buffer,size,FALSE));

	//像打開本地文件一樣,利用GDALopen 打開內存文件
	GDALAllRegister();
	GDALDataset* readDS = (GDALDataset*)GDALOpen("/vsimem/work",GA_ReadOnly);
	//釋放 內存文件
	VSIUnlink("/vsimem/work");
	
	int width = readDS->GetRasterXSize();
	int height = readDS->GetRasterYSize();
	int bandCount = readDS->GetRasterCount();
	float* data = new float[width*height*bandCount];
	if (readDS->RasterIO(GDALRWFlag::GF_Read,0,0,width,height,data,width,height,GDT_Float32,bandCount,NULL,0,0,0)==CE_Failure)
	{
		GDALClose(readDS);
		//釋放二進制數據流
		delete[] buffer;
		buffer = NULL;

		delete[] data;
		data = NULL;
	}

	GDALClose(readDS);
	delete[] buffer;
	buffer = NULL;
	//現在只需操縱data就好,用完釋放
	delete[] data;
	data = NULL;
這里需注意,內存中二進制數據流 buffer 的釋放是 在數據讀取結束才能做,否則會出現RasterIO 失敗。

這也正好說明,創建的內存文件 "/vsimem/work" 沒有重新分配內存保存圖像數據塊,而是指向二進制數據流 buffer。

 

參考:

http://cryolite.iteye.com/blog/358929

http://blog.csdn.net/liminlu0314/article/details/40209357

http://www.gdal.org/cpl__vsi_8h.html#af9c1b931449d423e7a80bacb75ff0717


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM