• GDAL从二进制数据流中构造数据集


    1. 概述

    参看《从二进制数据流中构造GDAL可以读取的图像数据》这篇文章。这个问题的内涵在于,处理图像时都会将其读取成宽X高X波段的三维数组的内存Buffer,但是图像文件本身却会被压缩成各种各样的数据类型(jpg、png、tif等)。在某些直接获取到数据流的情况下,可以直接在内存中构建GDAL数据集并进行读写操作,这样就可以避免磁盘IO的性能。

    以个人的实际经验来看,有两个地方用到了这个功能:

    1. 从远端(Web)访问数据,可以先一次性获取到内存Buffer,然后在内存中构建GDAL数据集。
    2. gltf的bin中内嵌了jpg/png图像文件,可以直接获取二进制文件流,然后在内存中构建GDAL数据集。

    2. 实现

    按照自己的使用习惯,试用了一下《从二进制数据流中构造GDAL可以读取的图像数据》的例子,基本没什么问题:

    #include <iostream>
    #include <gdal_priv.h>
    
    using namespace std;
    
    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 main()
    {
    	GDALAllRegister();          //GDAL所有操作都需要先注册格式
    	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");  //支持中文路径
    
    	// 为了构造内存文件,必须有一个内存文件名称,以/vsimem/开头,后面的随便啥都行
    	string osMemFileName = "/vsimem/00000000";
    
    	// 写了一个函数,读取二进制数据,也可以从数据库中或者网络啥的获取图像的二进制流存储在pabyData中
    	const char* imgPath = "D:/dst1.jpg";
    	int nDataSize = 0;
    	GByte* pabyData = GetStream(imgPath, nDataSize);
    
    	// 将二进制流构造到MEM文件中
    	VSIFCloseL(VSIFileFromMemBuffer(osMemFileName.c_str(), pabyData, nDataSize, FALSE));
    		
    	GDALDataset* img = (GDALDataset *)GDALOpen(imgPath, GA_ReadOnly);
    	if (!img)
    	{
    		cout << "Can't Open Image!" << endl;
    		return 1;
    	}
    
    	// 处理结束后,将内存文件进行释放
    	VSIUnlink(osMemFileName.c_str());
    
    	delete[] pabyData;
    	pabyData = nullptr;
    
    	int imgWidth = img->GetRasterXSize();   //图像宽度
    	int imgHeight = img->GetRasterYSize();  //图像高度
    	int bandNum = img->GetRasterCount();    //波段数
    	int depth = GDALGetDataTypeSize(img->GetRasterBand(1)->GetRasterDataType()) / 8;    //图像深度
    
    	cout << imgWidth << '	' << imgHeight << '	' << bandNum << '	' << depth << endl;
    
    	GDALClose(img);
    	img = nullptr;
    }
    

    读取到的宽、高、波段以及深度:
    imglink1

    也可以进行进一步的读写操作。

  • 相关阅读:
    设计模式之四 代理模式
    设计模式之四 建造者模式
    设计模式之三 模板模式
    设计模式之二 工厂模式
    如何使用Json-lib
    Java LoggingAPI 使用方法
    设计模式之一 单例模式
    Scrapy教程
    Scrapy简介
    Scrapy安装向导
  • 原文地址:https://www.cnblogs.com/charlee44/p/15501874.html
Copyright © 2020-2023  润新知