1. 程式人生 > >從二進制數據流中構造GDAL能夠讀取的圖像數據

從二進制數據流中構造GDAL能夠讀取的圖像數據

數據 delet seek emf width set content 讀取 折騰

在非常多時候。我們的圖像數據往往都不是文件方式存儲在磁盤上。而是可能從網絡或者數據庫中獲取的是二進制的圖像數據流。最簡單的方式和最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函數用來讀取一個數據流。具體的註視都在代碼裏面了。

從二進制數據流中構造GDAL能夠讀取的圖像數據