从二进制数据流中构造GDAL能够读取的图像数据

在非常多时候。我们的图像数据往往都不是文件方式存储在磁盘上。而是可能从网络或者数据库中获取的是二进制的图像数据流。最简单的方式和最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函数用来读取一个数据流。具体的注视都在代码里面了。

时间: 2024-12-28 13:23:05

从二进制数据流中构造GDAL能够读取的图像数据的相关文章

请教hhd转换字符在scanf中是不是把整数读取成char数据谢谢

ozv3ka49ik傧彼贤刮依司鬃久子救<http://weibo.com/p/230927987768625031028736> 7j3nj8g3j8合藤装月谂仑惹娇悔乃<http://weibo.com/p/230927987768721701347328> r71dpg36d1刂谎缸刀寥不祭辟魏宜<http://weibo.com/p/230927987768852106452992> 7ekbqeyjqi览粤菊嘶八苛涨抑诒恍<http://weibo.co

读取保存文件、图片在数据库中的上传读取

一.输入输出流 1.概念: 输入输出流主要用于保存.读取文件,其内容保存在内存中. 2.使用方法: using System.IO; //System.IO 命名空间包含允许读写文件和数据流的类型以及提供基本文件和目录支持的类型. 3.代码段实现读取和保存功能: 读取文字: OpenFileDialog op = new OpenFileDialog(); op.ShowDialog();//打开文件对话框 //将选择的东西读取到文档里 StreamReader sd = new StreamR

springboot请求体中的流只能读取一次的问题

场景交代 在springboot中添加拦截器进行权限拦截时,需要获取请求参数进行验证.当参数在url后面时(queryString)获取参数进行验证之后程序正常运行.但是,当请求参数在请求体中的时候,通过流的方式将请求体取出参数进行验证之后,发现后续流程抛出错误: Required request body is missing ... 经过排查,发现ServletInputStream的流只能读取一次(参考:httpServletRequest中的流只能读取一次的原因). 这就是为什么在拦截器

GDAL库——读取图像并提取基本信息

GDAL库是一个跨平台的栅格地理数据格式库,包括读取.写入.转换.处理各种栅格数据格式(有些特定的格式对一些操作如写入等不支持).它使用了一个单一的抽象数据模型就支持了大多数的栅格数据.这里有GDAL库支持的格式:http://www.gdal.org/formats_list.html 注:本文在Qt开发环境下使用GDAL库. 在Qt中使用GDAL库时,除了要加gdal_priv.h头文件外,还需要在xxx.pro文件内加上LIBS += -lgdal ,文件用可编辑的文档打开. 使用GDAL

涉及到复制和二进制日志中的选项和变量-Replication and Binary Logging Options and Variables

在搭建复制中,有些参数需要我们留意,在这里罗列出来,供大家参考一下,以GTID为基础 --server-id server-id:这是一个全局的可动态调整的变量,取值范围为0-4294967295,也就是2的32次方减1,这个选项必须在master和slave中都分别进行设置,如果不设置保持默认,则在连接过程中会产生错误.从而复制失败,将这个参数配置在my.cnf配置文件中,然后重启生效 2. --server_uuid server_uuid:这是一个全局只读的变量,非动态变量,以一个字符串的

检查处理kettle数据流中的空行

 检查处理kettle数据流中的空行 ETL处理过程中,有时需要生成数据,但是却没有输入数据,这可能有一些问题,所以通常需要ETL数据流产生一个空行数据:有时处理中需要一些聚集功能,则意味着当没有输入数据时,生成值为0:本文说明怎样检测并处理空行数据流. 示例场景 假设有需求需要读取输入数据代表销售(有三个字段:product产品名称.items_sold销售量.turnover销售金额).ETL处理流程需要计算产品的销售总量及销售总额:这里的处理大概是:从输入文件中读取多行数据,然后使用聚

数据流中的中位数-剑指Offer

数据流中的中位数 题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. 思路 我们可以用数组存,每次取中位数时需要排序 我们也可以用平衡二叉树存,不过构造树的过程很复杂 我们也可以用大小堆存,不过也不简单 最后我选择用java里现成的ArrayList存,用Collections.sort()方法排序 代码 import java.util.ArrayL

php接收二进制数据流转换成图片

<?php /** * 图片类 * @author [email protected] * @version 1.0 * PHP默认只识别application/x-www.form-urlencoded标准的数据类型. 因此,对型如text/xml 或者 soap 或者 application/octet-stream 之类的内容无法解析,如果用$_POST数组来接收就会失败! 故保留原型,交给$GLOBALS['HTTP_RAW_POST_DATA'] 来接收. 另外还有一项 php://i

《剑指offer》:[64]数据流中的中位数

题目:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数据排序后中间两个数的平均值. 例如:1,2,3,4,5的中位数为:3.1,2,3,4的中位数为:(2+3)/2=3. 方案一:采用Partition来解决.在[29]中我们讲过,快速查找中的Partition函数是十分重要,是一个比较常用的算法.所以这里我们采用partion函数来解决.从字符流里读字符,插入到一个无需的数组中的复杂度为