GDAL从二进制数据流中构造数据集
1. 概述
参看《从二进制数据流中构造GDAL可以读取的图像数据》这篇文章。这个问题的内涵在于,处理图像时都会将其读取成宽X高X波段的三维数组的内存Buffer,但是图像文件本身却会被压缩成各种各样的数据类型(jpg、png、tif等)。在某些直接获取到数据流的情况下,可以直接在内存中构建GDAL数据集并进行读写操作,这样就可以避免磁盘IO的性能。
以个人的实际经验来看,有两个地方用到了这个功能:
- 从远端(Web)访问数据,可以先一次性获取到内存Buffer,然后在内存中构建GDAL数据集。
- 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 << '\t' << imgHeight << '\t' << bandNum << '\t' << depth << endl;
GDALClose(img);
img = nullptr;
}
读取到的宽、高、波段以及深度:

也可以进行进一步的读写操作。
GDAL从二进制数据流中构造数据集的更多相关文章
- 从二进制数据流中构造GDAL可以读取的图像数据(C#)
在上一篇博客中,讲了一下使用GDAL从文件流中构造一个GDAL可以识别的数据来进行处理.原以为这个接口在C#中没有,仔细看了下GDAL库中源码,发现C#版本也有类似的函数,下面是GDAL库中的一个C# ...
- 从二进制数据流中构造GDAL可以读取的图像数据
在很多时候,我们的图像数据往往都不是文件方式存储在磁盘上,而是可能从网络或者数据库中获取的是二进制的图像数据流.最简单的方式和最容易想到的方式就是将这个文件流保存到磁盘上形成一个文件,然后再使用GDA ...
- 剑指offer 二进制1中的个数
算法-求二进制数中1的个数 问题描述 任意给定一个32位无符号整数n,求n的二进制表示中1的个数,比如n = 5(0101)时,返回2,n = 15(1111)时,返回4 这也是一道比较经典的题目了, ...
- 数据流中的第k大元素的golang实现
设计一个找到数据流中第K大元素的类(class).注意是排序后的第K大元素,不是第K个不同的元素. 你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器,它包含数据流中 ...
- 机器学习数据集,主数据集不能通过,人脸数据集介绍,从r包中获取数据集,中国河流数据集
机器学习数据集,主数据集不能通过,人脸数据集介绍,从r包中获取数据集,中国河流数据集 选自Microsoft www.tz365.Cn 作者:Lee Scott 机器之心编译 参与:李亚洲.吴攀. ...
- php 接收blob数据流,base64数据流 转为 blob二进制数据流
php正常接收参数的方式如下:$_GET$_POST$_REQUEST 但是如果跨语言接收请求参数的话,可能会出现一系列的问题,其他语言的http请求可能是基于数据流的概念来传递参数的,如果按照常规处 ...
- Windows下 ffmpeg + labelImg 提取视频帧 得到图片集 并 标注图片 来 构造数据集
构造数据集的流程 视频文件 >> ffmpeg处理 >> 图片集 >> labelImg进行标注 >> 标注好的数据集 准备ffmpeg ...
- [算法]最小的K个数和数据流中的中位数
1. 最小的K个数 题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 思路 Java 中的PriorityQueue是 ...
- C++中vector和堆的常用使用方法&例题:数据流中的中位数
vector常用函数: (1)a.size();//返回a中元素的个数: (2)a.push_back(5);//在a的最后一个向量后插入一个元素,其值为5 (3)a[i]; //返回a的第i个元素, ...
- php 接受处理二进制数据流并保存成图片
<form action="提交到处理地址" method="post" enctype="multipart/form-data" ...
随机推荐
- vue项目打包,解决静态资源无法加载和路由加载无效(404)问题
打包后的项目静态资源无法使用,导致页面空白 静态资源无法使用,那就说明项目打包后,图片和其他静态资源文件相对路径不对,此时找到config里面的index.js,在build模块下加入assetsPu ...
- CF1352D
题目简化和分析: 这题可以直接按照题意进行模拟,当然有些细节需要注意. 翻译的不足:这里的回合指任意一个人吃掉都算,而不是双方一个回合,最后一个人即使不满足也算一个回合. 我们可以采用两个指针模拟两个 ...
- P4870 [BalticOI 2009 Day1]甲虫 题解
题目链接 简要题意 在一个数轴上有 \(n\) 滴露水,每滴露水初始水量为 \(m\),每秒会蒸发一滴水,一个甲虫初始在原点,速度为 1,水能瞬间喝完,问它最多能喝到几滴水. 题目分析 对于这种移动区 ...
- MySQL简易教程
本文是参考廖雪峰老师的,但是网站广告有点多,我就在本地抄写一份,一方面是为了加强记忆巩固基础,另一方面也是就是为了第一方面.廖雪峰老师Mysql教程直达地址:https://www.liaoxuefe ...
- Util应用框架基础(一) - 依赖注入
本节介绍Util应用框架依赖注入的使用和配置扩展. 文章分为多个小节,如果对设计原理不感兴趣,只需阅读基础用法部分即可. 概述 当你想调用某个服务的方法完成特定功能时,首先需要得到这个服务的实例. 最 ...
- ORACLE 视图合并SQL优化案例
朋友给了一条SQL说跑8个小时才出结果,结果集很小75条数据,给他安排一下. SQL如下: SELECT DISTINCT T.XLA_TYPE, T.XLA_CODE, T.VENDOR_CODE, ...
- 该如何选择ClickHouse的表引擎
该如何选择ClickHouse的表引擎 本文将介绍ClickHouse中一个非常重要的概念-表引擎(table engine).如果对MySQL熟悉的话,或许你应该听说过InnoDB和MyISAM存储 ...
- 四个id 生成器性能比较记录
IdGenerator Seata 优化的雪花算法 Seata基于改良版雪花算法的分布式UUID生成器分析 关于新版雪花算法的答疑 csharp 移植代码 public class IdGenerat ...
- 题解 P7325
前言 数学符号约定 \(a,b,p\):表示任意自然数. \(F_x\):表示广义斐波那契数列的第 \(x\) 项. \(f_x\):表示普通斐波那契数列的第 \(x\) 项. 如非特殊说明,将会按照 ...
- (Good topic)单词的压缩编码(leetcode3.28每日打卡)
给定一个单词列表,我们将这个列表编码成一个索引字符串 S 与一个索引列表 A. 例如,如果这个列表是 ["time", "me", "bell&quo ...