GDAL中GDALDataset::RasterIO分块读取的实现
GDALDataset类中的RasterIO函数能够对图像任意指定区域、任意波段的数据按指定数据类型、指定排列方式读入内存和写入文件中,因此可以实现对大影像的分块读、写运算操作。针对特大的影像图像,有时为了减少内存消耗,对图像进行分块读取很有必要。在以下的测试代码中,给出了3种方式,每种方式的最终结果都是完全相同的,从内存占用情况来看:第一种大于第二种,第二种大于第三种。第三种消耗内存最小。
测试代码如下:
int test_gdal_GDALDataset()
{
const char* image_name = "E:/GitCode/GDAL_Test/test_images/3.jpg";
GDALAllRegister();
GDALDataset* poDataset = (GDALDataset*)GDALOpen(image_name, GA_ReadOnly);
if (poDataset == nullptr) {
std::cout << "input image error" << std::endl;
return -1;
}
int width = poDataset->GetRasterXSize();
int height = poDataset->GetRasterYSize();
int band_count = poDataset->GetRasterCount();
size_t length = width * height * band_count;
GDALDataType gdal_data_type = poDataset->GetRasterBand(1)->GetRasterDataType();
int depth = GDALGetDataTypeSize((GDALDataType)gdal_data_type);
//fprintf(stderr, "depth: %d\n", depth);
assert(depth == 8 || depth == 16);
int size_byte = 1;
if (depth == 16) size_byte = 2;
void* data1 = nullptr;
void* data2 = nullptr;
void* data3 = nullptr;
if (depth == 8) {
data1 = new unsigned char[length];
memset(data1, 0, length);
data2 = new unsigned char[length];
memset(data2, 0, length);
data3 = new unsigned char[length];
memset(data3, 0, length);
} else {
data1 = new unsigned short[length];
memset(data1, 0, length * 2);
data2 = new unsigned short[length];
memset(data2, 0, length * 2);
data3 = new unsigned short[length];
memset(data3, 0, length * 2);
}
GDALClose((GDALDatasetH)poDataset);
{ // mode1
GDALDataset* poDataset = (GDALDataset*)GDALOpen(image_name, GA_ReadOnly);
int band_count = poDataset->GetRasterCount();
fprintf(stderr, "mode=1: band_count = %d\n", band_count);
int* pBandMap = new int[band_count];
for (int i = 0; i < band_count; i++) {
pBandMap[i] = i + 1;
}
GDALDataType gdal_data_type = poDataset->GetRasterBand(1)->GetRasterDataType();
int depth = GDALGetDataTypeSize((GDALDataType)gdal_data_type);
void* poSrcData = nullptr;
if (depth == 8)
poSrcData = new unsigned char[width * height * band_count];
else
poSrcData = new unsigned short[width * height * band_count];
poDataset->RasterIO(GF_Read, 0, 0, width, height,
poSrcData, width, height, gdal_data_type, band_count, pBandMap, 0, 0, 0);
if (depth == 8) {
unsigned char* p1 = (unsigned char*)poSrcData;
for (int y = 0; y < height; y++) {
unsigned char* p2 = (unsigned char*)data1 + width * band_count * y;
for (int x = 0; x < width; x++) {
for (int band = 0; band < band_count; band++) {
p2[x * band_count + band] = p1[band * width * height + y * width + x];;
}
}
}
} else {
unsigned short* p1 = (unsigned short*)poSrcData;
for (int y = 0; y < height; y++) {
unsigned short* p2 = (unsigned short*)data1 + width * band_count * y;
for (int x = 0; x < width; x++) {
for (int band = 0; band < band_count; band++) {
p2[x * band_count + band] = p1[band * width * height + y * width + x];;
}
}
}
}
GDALClose((GDALDatasetH)poDataset);
delete[] pBandMap;
delete[] poSrcData;
}
{ // mode2
GDALDataset* poDataset = (GDALDataset*)GDALOpen(image_name, GA_ReadOnly);
int crop_width = 200;
int crop_height = 200;
int loops_y = height / crop_height;
int loops_x = width / crop_width;
for (int y = 0; y < loops_y; y++) {
for (int x = 0; x < loops_x; x++) {
int band_count = poDataset->GetRasterCount();
fprintf(stderr, "mode=2: band_count = %d\n", band_count);
int* pBandMap = new int[band_count];
for (int i = 0; i < band_count; i++) {
pBandMap[i] = i + 1;
}
GDALDataType gdal_data_type = poDataset->GetRasterBand(1)->GetRasterDataType();
int depth = GDALGetDataTypeSize((GDALDataType)gdal_data_type);
void* poSrcData = nullptr;
if (depth == 8)
poSrcData = new unsigned char[crop_width * crop_height * band_count];
else
poSrcData = new unsigned short[crop_width * crop_height * band_count];
int xOff = crop_width * x;
int yOff = crop_height * y;
poDataset->RasterIO(GF_Read, xOff, yOff, crop_width, crop_height,
poSrcData, crop_width, crop_height, gdal_data_type, band_count, pBandMap, 0, 0, 0);
if (depth == 8) {
unsigned char* p1 = (unsigned char*)poSrcData;
unsigned char* p2 = (unsigned char*)data2 + width * band_count * y * crop_height;
for (int m = 0; m < crop_height; m++) {
unsigned char* p3 = p2 + width * band_count * m + x * crop_width * band_count;
for (int n = 0; n < crop_width; n++) {
for (int band = 0; band < band_count; band++) {
p3[n * band_count + band] = p1[band * crop_width * crop_height + m * crop_width + n];
}
}
}
}
else {
unsigned short* p1 = (unsigned short*)poSrcData;
unsigned short* p2 = (unsigned short*)data2 + width * band_count * y * crop_height;
for (int m = 0; m < crop_height; m++) {
unsigned short* p3 = p2 + width * band_count * m + x * crop_width * band_count;
for (int n = 0; n < crop_width; n++) {
for (int band = 0; band < band_count; band++) {
p3[n * band_count + band] = p1[band * crop_width * crop_height + m * crop_width + n];
}
}
}
}
delete[] pBandMap;
delete[] poSrcData;
}
}
GDALClose((GDALDatasetH)poDataset);
}
{ // mode3
int crop_width = 200;
int crop_height = 200;
int loops_y = height / crop_height;
int loops_x = width / crop_width;
for (int y = 0; y < loops_y; y++) {
for (int x = 0; x < loops_x; x++) {
GDALDataset* poDataset = (GDALDataset*)GDALOpen(image_name, GA_ReadOnly);
int band_count = poDataset->GetRasterCount();
fprintf(stderr, "mode=3: band_count = %d\n", band_count);
int* pBandMap = new int[band_count];
for (int i = 0; i < band_count; i++) {
pBandMap[i] = i + 1;
}
GDALDataType gdal_data_type = poDataset->GetRasterBand(1)->GetRasterDataType();
int depth = GDALGetDataTypeSize((GDALDataType)gdal_data_type);
void* poSrcData = nullptr;
if (depth == 8)
poSrcData = new unsigned char[crop_width * crop_height * band_count];
else
poSrcData = new unsigned short[crop_width * crop_height * band_count];
int xOff = crop_width * x;
int yOff = crop_height * y;
poDataset->RasterIO(GF_Read, xOff, yOff, crop_width, crop_height,
poSrcData, crop_width, crop_height, gdal_data_type, band_count, pBandMap, 0, 0, 0);
if (depth == 8) {
unsigned char* p1 = (unsigned char*)poSrcData;
unsigned char* p2 = (unsigned char*)data3 + width * band_count * y * crop_height;
for (int m = 0; m < crop_height; m++) {
unsigned char* p3 = p2 + width * band_count * m + x * crop_width * band_count;
for (int n = 0; n < crop_width; n++) {
for (int band = 0; band < band_count; band++) {
p3[n * band_count + band] = p1[band * crop_width * crop_height + m * crop_width + n];
}
}
}
} else {
unsigned short* p1 = (unsigned short*)poSrcData;
unsigned short* p2 = (unsigned short*)data3 + width * band_count * y * crop_height;
for (int m = 0; m < crop_height; m++) {
unsigned short* p3 = p2 + width * band_count * m + x * crop_width * band_count;
for (int n = 0; n < crop_width; n++) {
for (int band = 0; band < band_count; band++) {
p3[n * band_count + band] = p1[band * crop_width * crop_height + m * crop_width + n];
}
}
}
}
GDALClose((GDALDatasetH)poDataset);
delete[] pBandMap;
delete[] poSrcData;
}
}
}
for (int i = 0; i < length * size_byte; i++) {
unsigned char* p1 = (unsigned char*)data1;
unsigned char* p2 = (unsigned char*)data2;
unsigned char* p3 = (unsigned char*)data3;
if (p1[i] != p2[i] || p1[i] != p3[i]) {
fprintf(stderr, "error: data1 != data2 or data1 != data3\n");
return -1;
}
}
delete[] data1;
delete[] data2;
delete[] data3;
return 0;
}
GitHub:https://github.com/fengbingchun/GDAL_Test
GDAL中GDALDataset::RasterIO分块读取的实现的更多相关文章
- GDAL中通过GDALDriver类的Create函数实现图像的保存
GDAL中除了读取各种类型的图像外,也可以实现对各种图像的保存操作,具体实现测试代码如下: int test_gadl_GDALDataset_write() { const char* image_ ...
- 分块读取Blob字段数据(Oracle)
试过了MSSQL的分块读取Blob字段,又尝试在Oracle下完成,发现还是可行的. 首先建立一个存储过程: create or replace procedure PRO_GET_BLOB( ...
- 分块读取Blob字段数据(MSSQL)
MSSQL中提供了一个功能,能够分块读取Blob字段中的数据,写了一个存储过程代码如下: CREATE PROCEDURE PRO_GET_FILE_DATA @PKG_ID INT, ...
- 此操作只能由 SQL Server 中拥有配置数据库读取权限的用户在已加入到某个服务器场的计算机上执行
错误提示:此操作只能由 SQL Server 中拥有配置数据库读取权限的用户在已加入到某个服务器场的计算机上执行.若要将此服务器连接到服务器场,请使用 SharePoint 产品配置向导,该向导可从 ...
- Delphi中使用python脚本读取Excel数据
Delphi中使用python脚本读取Excel数据2007-10-18 17:28:22标签:Delphi Excel python原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 . ...
- MySQL中游标使用以及读取文本数据
原文:MySQL中游标使用以及读取文本数据 前言 之前一直没有接触数据库的学习,只是本科时候修了一本数据库基本知识的课.当时只对C++感兴趣,天真的认为其它的课都没有用,数据库也是半懂不懂,胡乱就考试 ...
- 解决SpringMVC拦截器中Request数据只能读取一次的问题
解决SpringMVC拦截器中Request数据只能读取一次的问题 开发项目中,经常会直接在request中取数据,如Json数据,也经常用到@RequestBody注解,也可以直接通过request ...
- GDAL中GDALDataType中值与其在C++中数据类型对应
GDAL中的GDALDataType是一个枚举型,其中的值为: GDT_Unknown : 未知数据类型 GDT_Byte : 8bit正整型 (C++中对应unsigned char) GDT_UI ...
- java中Properties类及读取properties中属性值
本文为博主原创,未经允许不得转载: 在项目的应用中,经常将一些配置放入properties文件中,在代码应用中读取properties文件,就需要专门的类Properties类,通过这个类可以进行读取 ...
随机推荐
- 编程三基:cpu:算法,总线(io):一切皆文件;内存:运行空间
编程三基:cpu:算法,总线:一切皆文件:内存:数据.运行空间 原文找不到了.
- Yii 多表关联relations
1,首先多表关联是在models/xx.php的relations里配置的.而且是互配,但有区别.格式:'VarName'=>array('RelationType', 'ClassName', ...
- ResNet 修改
https://github.com/tornadomeet/ResNet apache 开源项目 修改如下: 训练模块 import argparse,logging,os import mxnet ...
- jquery分页例子
先看效果图: 实现原理很简单,使用了jquery.pagination这个插件,每当点击页码时异步去服务器去取该页的数据,简单介绍如下: 一.数据库表结构:很简单 就四个字段 分别是News_id ...
- 搭建nlp_server服务器
这是文档 如何启动斯坦福NLP-Service 1.sudo apt-get install gearman-job-server安装gearman-server 2.启动gearman服务: gea ...
- localStorage和cookie操作
localStorage和cookie操作代码: cookie: { isSupportCookie: function() { return navigator.cookieEnabled; }, ...
- python入门基础:文件的读写
文件的读写操作运用广泛,无论是何种语言都会涉及到文件的输入输出. 下面简单的总结一下文件的读写: 1:open()函数 f = open('workfile', 'w') 函数 open()返回文件的 ...
- 【luogu P2296 寻找道路】 题解
题目链接:https://www.luogu.org/problemnew/show/P2296 题意:给定起点终点,找一条从起点到终点的最短路径使路上的每个点都能有路径到达终点. 我们先反着建一遍图 ...
- 手工检测SQL注入(安全性测试)
手动你的ASP站可否注入: http://127.0.0.1/xx?id=11 and 1=1 (正常页面) http://127.0.0.1/xx?id=11 and 1=2 (出错页面) 检测表段 ...
- windows自带的netsh 端口转发
netsh interface portproxy show v4tov4 (3)添加“端口映射” netsh interface portproxy add v4tov4 listenaddress ...