On 3月31日, 下午5时46分, refactor <mjollnir....@gmail.com> wrote:
首先需要安装一个内存文件处理器
VSIInstallMemFileHandler();
不过调用VSIFOpenL()等函数时会自动调用这个安装函数,反复调用安装函数也没什么害处。
这个特殊的文件处理器可以将一段内存块作为文件处理,这些文件位于"/vsimem/" 目录下(不用找了,在shell下是看不到的),也就是说该目
录下的所有文件都被GDAL的内存文件处理器处理。不过目前还不支持目录操作,所以vsimem目录是平的。
可以用那些VSI*L函数创建和销毁内存里的数据,就像是操作文件一样。还有些方法可以高效的创建内存文件:不必拷贝原始的数据,这样同样的数据就不会
重复出现在多个地方了;可以将某段内存块关联成“GDAL内存文件系统"中的一个文件。
A. 将内存中的一块二进制影像数据流读入到GDALDataset,然后进行各种GDAL操作。
一个例子如下:
1. 影像二进制数据在内存中的位置为pabyInData,数据的长度为nInDataLength,我们为它创建一个内存影像文件
work.dat
VSIFCloseL( VSIFileFromMemBuffer( "/vsimem/work.dat", pabyInData,
nInDataLength, FALSE ) );
2. 打开这个内存影像文件,得到一个GDALDataset
GDALDatasetH hDS = GDALOpen( "/vsimem/work.dat", GA_ReadOnly );
B.将GDALDataset转换成某种格式(比如GTiff)的二进制影像数据流。一个例子如下
hDS为想输出为二进制数据的GDALDataset
1. 转换成目标数据格式的GDALDataset,这个GDALDataset是建立在“内存影像文件系统”上的
GDALDriverH hDriver = GDALGetDriverByName( "GTiff" );
GDALDatasetH hOutDS= GDALCreateCopy( hDriver, "/vsimem/out.tif", hDS,
TRUE, NULL,
NULL, NULL );
2. 调用VSIGetMemFileBuffer函数从内存影像文件中读出二进制数据流
vsi_l_offset outDataLength; // 读出的二进制数据流的长度放在这个变量里
GByte * binData = VSIGetMemFileBuffer("/vsimem/out.tif",
&outDataLength, TRUE);
binData为转换后的Gtif格式的二进制影像数据,outDataLength为影像数据的长度
VSI*函数内部会调用VSIInstallMemFileHandler();一般不需要直接调用
虽然还是原来的文件操作,但实际上是对内存直接操作的,只不过披上文件的外衣而已。
http://www.gdal.org/cpl__vsi_8h.html#66e2e6f093fd42f8a941b962d4c8a19e
不过我总是觉得没有什么应用需要直接得到PNG格式的流,因为在绘制API中,格式流还是要转成矩阵来用的,而BS结构也决定了导出文件比流处理更好
用。网络传输?那肯定是矩阵二进制流传更加方便快捷啦
用交换空间,交换文件的一定都是大文件或者要有版本控制的。
On 4月1日, 下午1时05分, refactor <mjollnir....@gmail.com> wrote: