GDAL直接操纵内存中的影像数据的办法

没有一个简单现成的函数可以做到这个,Frank Warmerdam提示了一种办法,使用“内存文件系统”,但不是通常linux下的那种内存文件系统,而是GDAL自定义的。

首先需要安装一个内存文件处理器
这个特殊的文件处理器可以将一段内存块作为文件处理,这些文件位于"/vsimem/" 目录下(不用找了,在shell下是看不到的),也就是说该目录下的所有文件都被GDAL的内存文件处理器处理。不过目前还不支持目录操作,所以vsimem目录是平的。另外不同的进程有各自的/vsimem/目录,而同一进程下的所有线程共享同一/vsimem/目录。

可以用那些VSI*L函数创建和销毁内存里的数据,就像是操作文件一样。还有些方法可以高效的创建内存文件:不必拷贝原始的数据,这样同样的数据就不会重复出现在多个地方了;可以将某段内存块关联成“GDAL内存文件系统"中的一个文件。


A. 将内存中的一块二进制影像数据buffer读入到GDALDataset

然后对GDALDataset进行各种GDAL操作。一个例子如下:

1. 影像二进制数据在内存中的位置为pabyInData,数据的长度为nInDataLength,我们为它创建一个内存影像文件work.dat
C代码  收藏代码

    VSIFCloseL( VSIFileFromMemBuffer( "/vsimem/work.dat", pabyInData,  
                                           nInDataLength, FALSE ) );  


2. 打开这个内存影像文件,得到一个GDALDataset
C代码  收藏代码

    GDALDatasetH hDS = GDALOpen( "/vsimem/work.dat", GA_ReadOnly );  



用完后记得要调用下列函数删除内存中的这个文件:
VSIUnlink( "/vsimem/work.dat" );


B.将GDALDataset转换成某种格式的二进制影像数据流。

举一个GTiff例子,hDS为想输出为二进制数据的GDALDataset
1. 转换成目标数据格式的GDALDataset,这个GDALDataset是建立在“内存影像文件系统”上的
C代码  收藏代码

    GDALDriverH hDriver = GDALGetDriverByName( "GTiff" );  
    GDALDatasetH hOutDS= GDALCreateCopy( hDriver, "/vsimem/out.tif", hDS, TRUE, NULL,   
                                 NULL, NULL );  


hOutDS是一个指向内存影像文件系统上的指针,不用自己关闭。

2. 调用VSIGetMemFileBuffer函数从内存影像文件中读出二进制数据流
C代码  收藏代码

    vsi_l_offset outDataLength;  // 读出的二进制数据流的长度放在这个变量里  
    int bUnlinkAndSeize = TRUE;  
    GByte * binData = VSIGetMemFileBuffer("/vsimem/out.tif", &outDataLength, bUnlinkAndSeize);  



binData为转换后的GTif格式的二进制影像数据,outDataLength为该影像数据的长度
bUnlinkAndSeize为TRUE的意思是,内存影像文件将会被自动删除,所以不必再调用VSIUnlink("/vsimem/out.tif")删除内存影像文件了(hOutDS也不用自己关闭);如果为FALSE,则会保留内存影像文件(hOutDS也要自己关闭)。

VSIGetMemFileBuffer函数分配的内存不要再用CPLFree函数释放:
C代码  收藏代码

    CPLFree(binData);  


否则可能出现double free错误,然后core dump。

VSI*函数内部会调用安装函数VSIInstallMemFileHandler();这个安装函数一般不需要直接调用,反复调用这个安装函数也没什么害处。

虽然还是原来的文件操作,但实际上是对内存直接操作的,只不过披上文件的外衣而已。
参考链接点这里:VSIInstallMemFileHandler。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
输出栅格影像数据通常需要使用 GDAL 库,下面是一些步骤: 1. 打开需要输出的栅格影像数据文件,可以使用 GDAL 的 Open 函数打开。 2. 创建输出文件,可以使用 GDAL 的 Create 函数创建一个新的栅格影像数据文件,也可以使用 GDAL 的 CreateCopy 函数从现有的栅格影像数据文件创建一个副本。 3. 设置输出文件的地理参考信息和投影信息,可以使用 GDAL 的 SetProjection 和 SetGeoTransform 函数设置。 4. 写入数据到输出文件,可以使用 GDAL 的 WriteRaster 函数写入数据。 5. 关闭输出文件,可以使用 GDAL 的 Close 函数关闭输出文件,释放资源。 下面是一个简单的示例代码: ```python from osgeo import gdal # 打开需要输出的栅格影像数据文件 input_filename = 'input.tif' input_dataset = gdal.Open(input_filename) # 创建输出文件 output_filename = 'output.tif' driver = gdal.GetDriverByName('GTiff') output_dataset = driver.Create(output_filename, input_dataset.RasterXSize, input_dataset.RasterYSize, input_dataset.RasterCount, input_dataset.GetRasterBand(1).DataType) # 设置输出文件的地理参考信息和投影信息 output_dataset.SetProjection(input_dataset.GetProjection()) output_dataset.SetGeoTransform(input_dataset.GetGeoTransform()) # 写入数据到输出文件 for i in range(input_dataset.RasterCount): band = input_dataset.GetRasterBand(i+1) output_band = output_dataset.GetRasterBand(i+1) output_band.WriteRaster(0, 0, input_dataset.RasterXSize, input_dataset.RasterYSize, band.ReadRaster(0, 0, input_dataset.RasterXSize, input_dataset.RasterYSize)) # 关闭输出文件 output_dataset = None ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值