GDALDataset类中的RasterIO函数能够对图像任意指定区域、任意波段的数据按指定数据类型、指定排列方式读入内存和写入文件中,因此可以实现对大影像的分块读、写运算操作。针对特大的影像图像,有时为了减少内存消耗,对图像进行分块读取很有必要。在以下的测试代码中,给出了3种方式,每种方式的最终结果都是完全相同的,从内存占用情况来看:第一种大于第二种,第二种大于第三种。第三种消耗内存最小。

测试代码如下:

  1. int test_gdal_GDALDataset()
  2. {
  3. const char* image_name = "E:/GitCode/GDAL_Test/test_images/3.jpg";
  4.  
  5. GDALAllRegister();
  6.  
  7. GDALDataset* poDataset = (GDALDataset*)GDALOpen(image_name, GA_ReadOnly);
  8. if (poDataset == nullptr) {
  9. std::cout << "input image error" << std::endl;
  10. return -1;
  11. }
  12.  
  13. int width = poDataset->GetRasterXSize();
  14. int height = poDataset->GetRasterYSize();
  15. int band_count = poDataset->GetRasterCount();
  16. size_t length = width * height * band_count;
  17.  
  18. GDALDataType gdal_data_type = poDataset->GetRasterBand(1)->GetRasterDataType();
  19. int depth = GDALGetDataTypeSize((GDALDataType)gdal_data_type);
  20. //fprintf(stderr, "depth: %d\n", depth);
  21. assert(depth == 8 || depth == 16);
  22. int size_byte = 1;
  23. if (depth == 16) size_byte = 2;
  24.  
  25. void* data1 = nullptr;
  26. void* data2 = nullptr;
  27. void* data3 = nullptr;
  28.  
  29. if (depth == 8) {
  30. data1 = new unsigned char[length];
  31. memset(data1, 0, length);
  32. data2 = new unsigned char[length];
  33. memset(data2, 0, length);
  34. data3 = new unsigned char[length];
  35. memset(data3, 0, length);
  36. } else {
  37. data1 = new unsigned short[length];
  38. memset(data1, 0, length * 2);
  39. data2 = new unsigned short[length];
  40. memset(data2, 0, length * 2);
  41. data3 = new unsigned short[length];
  42. memset(data3, 0, length * 2);
  43. }
  44.  
  45. GDALClose((GDALDatasetH)poDataset);
  46.  
  47. { // mode1
  48. GDALDataset* poDataset = (GDALDataset*)GDALOpen(image_name, GA_ReadOnly);
  49. int band_count = poDataset->GetRasterCount();
  50. fprintf(stderr, "mode=1: band_count = %d\n", band_count);
  51. int* pBandMap = new int[band_count];
  52. for (int i = 0; i < band_count; i++) {
  53. pBandMap[i] = i + 1;
  54. }
  55. GDALDataType gdal_data_type = poDataset->GetRasterBand(1)->GetRasterDataType();
  56. int depth = GDALGetDataTypeSize((GDALDataType)gdal_data_type);
  57. void* poSrcData = nullptr;
  58. if (depth == 8)
  59. poSrcData = new unsigned char[width * height * band_count];
  60. else
  61. poSrcData = new unsigned short[width * height * band_count];
  62.  
  63. poDataset->RasterIO(GF_Read, 0, 0, width, height,
  64. poSrcData, width, height, gdal_data_type, band_count, pBandMap, 0, 0, 0);
  65.  
  66. if (depth == 8) {
  67. unsigned char* p1 = (unsigned char*)poSrcData;
  68.  
  69. for (int y = 0; y < height; y++) {
  70. unsigned char* p2 = (unsigned char*)data1 + width * band_count * y;
  71. for (int x = 0; x < width; x++) {
  72. for (int band = 0; band < band_count; band++) {
  73. p2[x * band_count + band] = p1[band * width * height + y * width + x];;
  74. }
  75. }
  76. }
  77. } else {
  78. unsigned short* p1 = (unsigned short*)poSrcData;
  79.  
  80. for (int y = 0; y < height; y++) {
  81. unsigned short* p2 = (unsigned short*)data1 + width * band_count * y;
  82. for (int x = 0; x < width; x++) {
  83. for (int band = 0; band < band_count; band++) {
  84. p2[x * band_count + band] = p1[band * width * height + y * width + x];;
  85. }
  86. }
  87. }
  88. }
  89.  
  90. GDALClose((GDALDatasetH)poDataset);
  91. delete[] pBandMap;
  92. delete[] poSrcData;
  93. }
  94.  
  95. { // mode2
  96. GDALDataset* poDataset = (GDALDataset*)GDALOpen(image_name, GA_ReadOnly);
  97.  
  98. int crop_width = 200;
  99. int crop_height = 200;
  100. int loops_y = height / crop_height;
  101. int loops_x = width / crop_width;
  102.  
  103. for (int y = 0; y < loops_y; y++) {
  104. for (int x = 0; x < loops_x; x++) {
  105. int band_count = poDataset->GetRasterCount();
  106. fprintf(stderr, "mode=2: band_count = %d\n", band_count);
  107. int* pBandMap = new int[band_count];
  108. for (int i = 0; i < band_count; i++) {
  109. pBandMap[i] = i + 1;
  110. }
  111. GDALDataType gdal_data_type = poDataset->GetRasterBand(1)->GetRasterDataType();
  112. int depth = GDALGetDataTypeSize((GDALDataType)gdal_data_type);
  113. void* poSrcData = nullptr;
  114. if (depth == 8)
  115. poSrcData = new unsigned char[crop_width * crop_height * band_count];
  116. else
  117. poSrcData = new unsigned short[crop_width * crop_height * band_count];
  118.  
  119. int xOff = crop_width * x;
  120. int yOff = crop_height * y;
  121.  
  122. poDataset->RasterIO(GF_Read, xOff, yOff, crop_width, crop_height,
  123. poSrcData, crop_width, crop_height, gdal_data_type, band_count, pBandMap, 0, 0, 0);
  124.  
  125. if (depth == 8) {
  126. unsigned char* p1 = (unsigned char*)poSrcData;
  127. unsigned char* p2 = (unsigned char*)data2 + width * band_count * y * crop_height;
  128.  
  129. for (int m = 0; m < crop_height; m++) {
  130. unsigned char* p3 = p2 + width * band_count * m + x * crop_width * band_count;
  131. for (int n = 0; n < crop_width; n++) {
  132. for (int band = 0; band < band_count; band++) {
  133. p3[n * band_count + band] = p1[band * crop_width * crop_height + m * crop_width + n];
  134. }
  135. }
  136. }
  137.  
  138. }
  139. else {
  140. unsigned short* p1 = (unsigned short*)poSrcData;
  141. unsigned short* p2 = (unsigned short*)data2 + width * band_count * y * crop_height;
  142.  
  143. for (int m = 0; m < crop_height; m++) {
  144. unsigned short* p3 = p2 + width * band_count * m + x * crop_width * band_count;
  145. for (int n = 0; n < crop_width; n++) {
  146. for (int band = 0; band < band_count; band++) {
  147. p3[n * band_count + band] = p1[band * crop_width * crop_height + m * crop_width + n];
  148. }
  149. }
  150. }
  151. }
  152.  
  153. delete[] pBandMap;
  154. delete[] poSrcData;
  155. }
  156. }
  157.  
  158. GDALClose((GDALDatasetH)poDataset);
  159. }
  160.  
  161. { // mode3
  162. int crop_width = 200;
  163. int crop_height = 200;
  164. int loops_y = height / crop_height;
  165. int loops_x = width / crop_width;
  166.  
  167. for (int y = 0; y < loops_y; y++) {
  168. for (int x = 0; x < loops_x; x++) {
  169. GDALDataset* poDataset = (GDALDataset*)GDALOpen(image_name, GA_ReadOnly);
  170. int band_count = poDataset->GetRasterCount();
  171. fprintf(stderr, "mode=3: band_count = %d\n", band_count);
  172. int* pBandMap = new int[band_count];
  173. for (int i = 0; i < band_count; i++) {
  174. pBandMap[i] = i + 1;
  175. }
  176. GDALDataType gdal_data_type = poDataset->GetRasterBand(1)->GetRasterDataType();
  177. int depth = GDALGetDataTypeSize((GDALDataType)gdal_data_type);
  178. void* poSrcData = nullptr;
  179. if (depth == 8)
  180. poSrcData = new unsigned char[crop_width * crop_height * band_count];
  181. else
  182. poSrcData = new unsigned short[crop_width * crop_height * band_count];
  183.  
  184. int xOff = crop_width * x;
  185. int yOff = crop_height * y;
  186.  
  187. poDataset->RasterIO(GF_Read, xOff, yOff, crop_width, crop_height,
  188. poSrcData, crop_width, crop_height, gdal_data_type, band_count, pBandMap, 0, 0, 0);
  189.  
  190. if (depth == 8) {
  191. unsigned char* p1 = (unsigned char*)poSrcData;
  192. unsigned char* p2 = (unsigned char*)data3 + width * band_count * y * crop_height;
  193.  
  194. for (int m = 0; m < crop_height; m++) {
  195. unsigned char* p3 = p2 + width * band_count * m + x * crop_width * band_count;
  196. for (int n = 0; n < crop_width; n++) {
  197. for (int band = 0; band < band_count; band++) {
  198. p3[n * band_count + band] = p1[band * crop_width * crop_height + m * crop_width + n];
  199. }
  200. }
  201. }
  202.  
  203. } else {
  204. unsigned short* p1 = (unsigned short*)poSrcData;
  205. unsigned short* p2 = (unsigned short*)data3 + width * band_count * y * crop_height;
  206.  
  207. for (int m = 0; m < crop_height; m++) {
  208. unsigned short* p3 = p2 + width * band_count * m + x * crop_width * band_count;
  209. for (int n = 0; n < crop_width; n++) {
  210. for (int band = 0; band < band_count; band++) {
  211. p3[n * band_count + band] = p1[band * crop_width * crop_height + m * crop_width + n];
  212. }
  213. }
  214. }
  215. }
  216.  
  217. GDALClose((GDALDatasetH)poDataset);
  218. delete[] pBandMap;
  219. delete[] poSrcData;
  220. }
  221. }
  222. }
  223.  
  224. for (int i = 0; i < length * size_byte; i++) {
  225. unsigned char* p1 = (unsigned char*)data1;
  226. unsigned char* p2 = (unsigned char*)data2;
  227. unsigned char* p3 = (unsigned char*)data3;
  228.  
  229. if (p1[i] != p2[i] || p1[i] != p3[i]) {
  230. fprintf(stderr, "error: data1 != data2 or data1 != data3\n");
  231. return -1;
  232. }
  233. }
  234.  
  235. delete[] data1;
  236. delete[] data2;
  237. delete[] data3;
  238.  
  239. return 0;
  240. }

GitHub:https://github.com/fengbingchun/GDAL_Test

GDAL中GDALDataset::RasterIO分块读取的实现的更多相关文章

  1. GDAL中通过GDALDriver类的Create函数实现图像的保存

    GDAL中除了读取各种类型的图像外,也可以实现对各种图像的保存操作,具体实现测试代码如下: int test_gadl_GDALDataset_write() { const char* image_ ...

  2. 分块读取Blob字段数据(Oracle)

    试过了MSSQL的分块读取Blob字段,又尝试在Oracle下完成,发现还是可行的. 首先建立一个存储过程: create or replace procedure PRO_GET_BLOB(     ...

  3. 分块读取Blob字段数据(MSSQL)

    MSSQL中提供了一个功能,能够分块读取Blob字段中的数据,写了一个存储过程代码如下: CREATE PROCEDURE PRO_GET_FILE_DATA     @PKG_ID INT,     ...

  4. 此操作只能由 SQL Server 中拥有配置数据库读取权限的用户在已加入到某个服务器场的计算机上执行

    错误提示:此操作只能由 SQL Server 中拥有配置数据库读取权限的用户在已加入到某个服务器场的计算机上执行.若要将此服务器连接到服务器场,请使用 SharePoint 产品配置向导,该向导可从 ...

  5. Delphi中使用python脚本读取Excel数据

    Delphi中使用python脚本读取Excel数据2007-10-18 17:28:22标签:Delphi Excel python原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 . ...

  6. MySQL中游标使用以及读取文本数据

    原文:MySQL中游标使用以及读取文本数据 前言 之前一直没有接触数据库的学习,只是本科时候修了一本数据库基本知识的课.当时只对C++感兴趣,天真的认为其它的课都没有用,数据库也是半懂不懂,胡乱就考试 ...

  7. 解决SpringMVC拦截器中Request数据只能读取一次的问题

    解决SpringMVC拦截器中Request数据只能读取一次的问题 开发项目中,经常会直接在request中取数据,如Json数据,也经常用到@RequestBody注解,也可以直接通过request ...

  8. GDAL中GDALDataType中值与其在C++中数据类型对应

    GDAL中的GDALDataType是一个枚举型,其中的值为: GDT_Unknown : 未知数据类型 GDT_Byte : 8bit正整型 (C++中对应unsigned char) GDT_UI ...

  9. java中Properties类及读取properties中属性值

    本文为博主原创,未经允许不得转载: 在项目的应用中,经常将一些配置放入properties文件中,在代码应用中读取properties文件,就需要专门的类Properties类,通过这个类可以进行读取 ...

随机推荐

  1. slf4j-api-1.5.8.jar

    资源介绍: 详细说明:slf4j-api-1.5.8.jar,jsp开发中使用FCK编辑器,要用到一个jar包-slf4j-api-1.5.8.jar, jsp development using t ...

  2. 通过JAVA从MQ读取消息的时候报错及解决

    如果是通过JAVA将消息写入到MQ,再通过JAVA去读取消息,采用MQMessage读消息的方法readUTF()去读取的时候,就不会报错,可以正常读出来.如果采用在MQ资源管理器中插入测试消息或者是 ...

  3. Apache 在不同平台和版本上的默认文件布局

    https://wiki.apache.org/httpd/DistrosDefaultLayout This guide lists the default installation layouts ...

  4. BZOJ2118:墨墨的等式(最短路)

    Description 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在 ...

  5. Ajax实例一:利用服务器计算

    Ajax实例一:利用服务器计算 HTML代码 //输入两个数 <input id="number1" type="number"> <inpu ...

  6. maven 根据P参数值打包动态修改properties文件中值或一定properties

    需求:由于最近开发clover项目 ,没有使用spring,更没有使用任何框架,而使用J2EE的web工程,所以连接ZK和MongoDB.Redis等服务器需用指定properties文件, 而目前公 ...

  7. 利用Apache Isis快速原型化-宠物诊所的宠物管理

    前言 Apache Isis是DDD方法的一个实现框架. 需求分析 宠物诊所需要记录宠物的资料,包括类型.名字.及其主人. 多个宠物可能同属于一个主人. 宠物可能更换主人. 宠物主人记录姓名,我们可以 ...

  8. flask总结之session,websocket,上下文管理

    1.关于session flask是带有session的,它加密后存储在用户浏览器的cookie中,可以通过app.seesion_interface源码查看 from flask import Fl ...

  9. day 03 --Haproxy 增加, 删除,查询

    key 知识点:函数的定义, 函数的递归调用, flag 标志位的使用,eval() 函数 #!C:\Program Files\Python35\bin # -*- conding:utf-8 -* ...

  10. NLP语言模型

    语言模型: I. 基本思想 区别于其他大多数检索模型从查询到文档(即给定用户查询,如何找出相关的文档), 语言模型由文档到查询,即为每个文档建立不同的语言模型,判断由文档生成用户查 询的可能性有多大, ...