gdal有没有办法直接操纵内存中的影像数据

65 views
Skip to first unread message

refactor

unread,
Mar 31, 2009, 5:46:09 AM3/31/09
to gdal+python+GIS+geosings论坛
GDALOpen要打开文件系统上的影像文件,如果影像数据不是来自文件,而是通过socket传来的(例如,网络传来的一个jpg格式的二进制数
据),能否“直接”用gdal操作内存中的数据

refactor

unread,
Mar 31, 2009, 6:53:23 AM3/31/09
to gdal+python+GIS+geosings论坛
找到了这个东东:http://www.gdal.org/frmt_mem.html
继续探索中,

linux23...@gmail.com

unread,
Mar 31, 2009, 9:44:23 AM3/31/09
to gdal+python+GIS+geosings论坛
呵呵,非常好,善于自己找答案

refactor

unread,
Mar 31, 2009, 10:46:39 AM3/31/09
to gdal+python+GIS+geosings论坛
或者,GDAL读取的数据直接转换成另一种格式的二进制数据流,而不是通过文件
比如读取的JPEG文件得到一个dataset,怎么通过GDAL将数据转换成一个png格式的二进制数据流,而不是间接通过文件的方式呢

On 3月31日, 下午5时46分, refactor <mjollnir....@gmail.com> wrote:

refactor

unread,
Apr 1, 2009, 1:05:44 AM4/1/09
to gdal+python+GIS+geosings论坛
没有一个简单现成的函数可以做到这个,Frank Warmerdam提示了一种办法,使用“内存文件系统”,当不是通常linux下的那种内存文件系
统,而是GDAL自定义的。

首先需要安装一个内存文件处理器
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

linux23...@gmail.com

unread,
Apr 1, 2009, 10:59:59 PM4/1/09
to gdal+python+GIS+geosings论坛
主要看在内存中怎么操作。数据从哪来?往哪去?反正在内存中不需要有格式的概念。都是2进制数据的矩阵阿。你操作矩阵就是了。至于你要往哪里输出跟用什
么底层都没关系阿。数据读进内存后,怎么操作都由你。跟原来什么格式,以后什么格式都没有关系了。

linux23...@gmail.com

unread,
Apr 1, 2009, 11:09:49 PM4/1/09
to gdal+python+GIS+geosings论坛
使用中间交换文件只是在大数据量的时候,没办法一次把数据全部读入内存的时候才用的。如果数据量小,直接操作矩阵了,没必要再创建内存数据集。在应用的
时候,可以通过PIL之类的图像库,把矩阵转化成格式化数据。或者通过流的重定向,或者通过库的API,就可以获得格式化二进制流,

不过我总是觉得没有什么应用需要直接得到PNG格式的流,因为在绘制API中,格式流还是要转成矩阵来用的,而BS结构也决定了导出文件比流处理更好
用。网络传输?那肯定是矩阵二进制流传更加方便快捷啦

用交换空间,交换文件的一定都是大文件或者要有版本控制的。

On 4月1日, 下午1时05分, refactor <mjollnir....@gmail.com> wrote:

Reply all
Reply to author
Forward
0 new messages