当前位置:   article > 正文

C++下GDAL的详细使用案例(含项目配置、tif读取为cv::Mat、Mat保存为tif)_c++ gdal

c++ gdal

1、GDAL的安装与配置

1.1 GDAL的下载安装

直接到下列链接下载即可,按照说明,将bin目录添加的系统环境变量中即可

windows下GDAL322的库-深度学习文档类资源-CSDN下载

1.2 vs中GDAL的配置

包含目录中设置include目录

 库目录中设置lib的路径

 附加依赖项中设置gdal_i.lib

 

2、GDAL读取数据

GDAL读取数钱需要注册一下驱动(用于编码解码图像的驱动),同时可以设置一下支持中文路径。加载数据时需要注意,GA_Update和GA_ReadOnly两种模式。

  1. GDALAllRegister();//注册所有的驱动
  2. CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); //设置支持中文路径和文件名
  3. //1、加载tif数据
  4. string file_path_name = "test.tif";
  5. //std::cout << "请输入图片路径:" << std::endl;
  6. //std::cin >> file_path_name;
  7. GDALDataset* poDataset = (GDALDataset*)GDALOpen(file_path_name.c_str(), GA_ReadOnly);//GA_Update和GA_ReadOnly两种模式
  8. if (poDataset == NULL)
  9. {
  10. std::cout << "指定的文件不能打开!" << std::endl;
  11. return 0;
  12. }

2.1 获取图像的尺寸

这里所有的波段的size都是一样的

  1. int nImgSizeX = poDataset->GetRasterXSize();
  2. int nImgSizeY = poDataset->GetRasterYSize();
  3. std::cout << "ImageX = " << nImgSizeX << ", ImageY = " << nImgSizeY << std::endl;

2.2 获取图像的通道数

  1. int bandCount = poDataset->GetRasterCount();
  2. std::cout << "bandCount = " << bandCount << std::endl;

2.3 获取特定波段

需要注意的是在GDAL中波段数的起始数是1,而非0

    GDALRasterBand* poBand1 = poDataset->GetRasterBand(1);

2.4 获取数据类型

根据波段获取数据类型,而数据中有多个波段。由此可知,每一个波段都可以有不同的数据类型。

  1. GDALDataType g_type = GDALDataType(poBand1->GetRasterDataType());
  2. std::cout << "g_type = " << g_type << std::endl;

GDAL中共有12种数据类型,具体如下所示

  1. typedef enum {
  2. GDT_Unknown = 0,
  3. GDT_Byte = 1,
  4. GDT_UInt16 = 2,
  5. GDT_Int16 = 3,
  6. GDT_UInt32 = 4,
  7. GDT_Int32 = 5,GDT_UInt64,GDT_Int64
  8. GDT_Float32 = 6,
  9. GDT_Float64 = 7,
  10. GDT_CInt16 = 8,
  11. GDT_CInt32 = 9,GDT_CInt64
  12. GDT_CFloat32 = 10,
  13. GDT_CFloat64 = 11,
  14. GDT_TypeCount = 12
  15. } GDALDataType;

3、坐标系与投影信息处理

3.1 获取及设置坐标变换系数

坐标变换系数的具体格式为左上角x坐标, 水平分辨率,旋转参数, 左上角y坐标,旋转参数,竖直分辨率。对应同一区域不同级别的的图像,只有水平分辨率(trans[1])与竖直分辨率(trans[5])的值不一样。其默认值为{ 0,1,0,0,0,1 },即x、y分辨率为1,其他信息为0 。

  1. double trans[6] = { 0,1,0,0,0,1 };//定义为默认值,即x、y分辨率为1,其他信息为0
  2. //具体格式为左上角x坐标, 水平分辨率,旋转参数, 左上角y坐标,旋转参数,竖直分辨率。对应同一区域不同级别的的图像,只有水平分辨率(trans[1])与竖直分辨率(trans[5])的值不一样
  3. CPLErr aaa = poDataset->GetGeoTransform(trans);
  4. trans[2] = 0.3;//修改x的旋转参数信息
  5. trans[4] = 0.1;//修改y的旋转参数信息
  6. //poDataset->SetGeoTransform(trans);//设置坐标变换系数
  7. std::cout << "trans = " << trans[0] << "," << trans[1] << "," << trans[2] << "," << trans[3] << "," << trans[4] << "," << trans[5] << std::endl;

3.2 像素坐标与投影坐标的相互转换

下面实现了经纬度坐标与像素坐标的相互转换

  1. double dProjX, dProjY;
  2. int iCol, iRow;
  3. iCol = 111;
  4. iRow = 111;
  5. ImageRowCol2Projection(trans, iCol, iRow, dProjX, dProjY);
  6. std::cout << "在trans中,像素坐标=》经纬度:" << iCol << "," << iRow << "====》" << dProjX << "," << dProjY << std::endl;
  7. Projection2ImageRowCol(trans, dProjX, dProjY, iCol, iRow);
  8. std::cout << "在trans中,经纬度=》像素坐标:" << dProjX << "," << dProjY << "====》" << iCol << "," << iRow << std::endl;

两个转换函数的定义如下所示,参考了关于GDAL计算图像坐标的几个问题_IvanLJF的博客-CSDN博客 

  1. //计算trans中图片xy点的经纬度信息
  2. //adfGeoTransform的6个参数分别为左上角x坐标,水平分辨率,旋转参数,左上角y坐标,旋转参数,竖直分辨率,一般来说,旋转参数都为0
  3. bool Projection2ImageRowCol(double* adfGeoTransform, double dProjX, double dProjY, int& iCol, int& iRow)
  4. {
  5. try
  6. {
  7. double dTemp = adfGeoTransform[1] * adfGeoTransform[5] - adfGeoTransform[2] * adfGeoTransform[4];
  8. double dCol = 0.0, dRow = 0.0;
  9. dCol = (adfGeoTransform[5] * (dProjX - adfGeoTransform[0]) -
  10. adfGeoTransform[2] * (dProjY - adfGeoTransform[3])) / dTemp + 0.5;
  11. dRow = (adfGeoTransform[1] * (dProjY - adfGeoTransform[3]) -
  12. adfGeoTransform[4] * (dProjX - adfGeoTransform[0])) / dTemp + 0.5;
  13. iCol = int(dCol);
  14. iRow = int(dRow);
  15. return true;
  16. }
  17. catch (...)
  18. {
  19. return false;
  20. }
  21. }
  22. bool ImageRowCol2Projection(double* adfGeoTransform, int iCol, int iRow, double& dProjX, double& dProjY)
  23. {
  24. try
  25. {
  26. dProjX = adfGeoTransform[0] + adfGeoTransform[1] * iCol + adfGeoTransform[2] * iRow;
  27. dProjY = adfGeoTransform[3] + adfGeoTransform[4] * iCol + adfGeoTransform[5] * iRow;
  28. return true;
  29. }
  30. catch (...)
  31. {
  32. return false;
  33. }
  34. }

3.3 获取与设置投影坐标系信息

在GDAL数据坐标系中有WGS84坐标系、CGCS2000坐标系、GCJ02坐标系、BD09坐标系等。具体可分为地心坐标系、投影坐标系、原始坐标系、加密坐标系4类。更多坐标系信息可以参考https://blog.csdn.net/sinat_41310868/article/details/115551276

  1. std::string projs = poDataset->GetProjectionRef();
  2. //设置地理坐标系信息
  3. //poDataset->SetProjection(projs.c_str());
  4. std::cout << "projs = " << projs << std::endl;

4、读写GDAL数据

4.1 将数据读取到Mat中

需要注意的是cv::Mat创建时,是(height,width)的格式,与GDAL的(width,height)刚好相反。同时GADL的起始通道数是1,不是0.

  1. cv::Mat gdal_mat1(nImgSizeY, nImgSizeX, CV_8UC1, Scalar(0));
  2. cv::Mat gdal_mat2(nImgSizeY, nImgSizeX, CV_8UC1, Scalar(0));
  3. cv::Mat gdal_mat3(nImgSizeY, nImgSizeX, CV_8UC1, Scalar(0));
  4. poDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, 0, nImgSizeX, nImgSizeY, gdal_mat1.data, nImgSizeX, nImgSizeY, g_type, 0, 0);
  5. poDataset->GetRasterBand(2)->RasterIO(GF_Read, 0, 0, nImgSizeX, nImgSizeY, gdal_mat2.data, nImgSizeX, nImgSizeY, g_type, 0, 0);
  6. poDataset->GetRasterBand(3)->RasterIO(GF_Read, 0, 0, nImgSizeX, nImgSizeY, gdal_mat3.data, nImgSizeX, nImgSizeY, g_type, 0, 0);
  7. cv::Mat mg;
  8. cv::merge(vector<cv::Mat>{ gdal_mat3, gdal_mat2, gdal_mat1,}, mg);
  9. cv::imwrite("read_save.jpg", mg);

RasterIO函数的参数列表如下所示。从参数列表中是可以看到,GDAL是支持将数据分块读入的内存中的 。RasterIO参数列表的详细说明可以参考 https://blog.51cto.com/u_15469043/4903358

  1. CPLErr GDALRasterBand::RasterIO ( GDALRWFlag eRWFlag,
  2. int nXOff,//x的起始点
  3. int nYOff,//y的起始点
  4. int nXSize,//读取窗口的宽
  5. int nYSize,//读取窗口的高
  6. void * pData,
  7. int nBufXSize,//与nXSize相同
  8. int nBufYSize,//与nYSize相同
  9. GDALDataType eBufType,
  10. int nPixelSpace,//通常默认为0
  11. int nLineSpace //通常默认为0
  12. )

除了将数据读取到mat中外,我们还可以将数据读取到指针或者数组中

  1. //void * malloc(size_t n):给指针分配相应的内存,并返回内存空间的首地址。当内存不再使用的时候,应使用free()函数将内存块释放掉。
  2. uint8_t* srcData = (uint8_t*)malloc(sizeof(uint8_t) * nImgSizeX * nImgSizeY);
  3. //void * memset (void * p,int c,size_t n):将p中的n个字节都赋值为c
  4. memset(srcData, 0, sizeof(uint8_t) * 1 * nImgSizeX * nImgSizeY);//为空间赋默认值0
  5. poDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, 0, nImgSizeX, nImgSizeY, srcData, nImgSizeX, nImgSizeY, g_type, 0, 0);

4.2 将mat数据保存到GDAL中(tiff格式)

创建gdal对象   一次性写入数据,只支持tiff数据。PEN、JPEG等驱动没有实现相应的Create方法。

  1. int nImgSizeX3 = gdal_mat1.cols;
  2. int nImgSizeY3 = gdal_mat1.rows;
  3. GDALDriver* pDriverMEM3 = GetGDALDriverManager()->GetDriverByName("GTiff");
  4. if (!pDriverMEM3) {
  5. fprintf(stderr, "get driver by name failed\n");
  6. return -1;
  7. }
  8. int nBands3 = 1;
  9. GDALDataset* poDataset3 = pDriverMEM3->Create("saved3.tif", nImgSizeX3, nImgSizeY3, nBands3, g_type, NULL);
  10. if (!poDataset3) {
  11. fprintf(stderr, "Create GDALDataset failed\n");
  12. return -1;
  13. }
  14. poDataset3->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, nImgSizeX3, nImgSizeY3, gdal_mat1.data, nImgSizeX3, nImgSizeY3, GDT_Byte, 0, 0);
  15. std::cout << "tif 文件保存成功" << std::endl;

4.3 将mat数据保存到GDAL中(任意格式)

GDAL中可用的驱动格式还有:BMP、JPEG、PNG、GTiff、GIF、HFA、BT、ECW、FITS、HDF4、EHdr。这些驱动格式分别对应着不同的文件类型,MEM表示为内存对象,可以快速的分块追加写入数据。MEM文件大小是和你的系统内存大小有关系,并不会存储到磁盘中。

  1. int nImgSizeX2 = gdal_mat1.cols;
  2. int nImgSizeY2 = gdal_mat1.rows;
  3. //获取GDAL驱动
  4. GDALDriver* pDriverMEM = GetGDALDriverManager()->GetDriverByName("MEM");
  5. int nBands = 1;
  6. //创建GDAL对象,只保存原图的一个通道
  7. //Create(const char * pszName,int nXSize, int nYSize, int nBands, GDALDataType eType, char** papszOptions)
  8. GDALDataset* poDataset2 = pDriverMEM->Create("", nImgSizeX2, nImgSizeY2, nBands, g_type, NULL);
  9. //将mat数据写入到GDALDataset中
  10. poDataset2->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, nImgSizeX2, nImgSizeY2, gdal_mat1.data, nImgSizeX2, nImgSizeY2, GDT_Byte, 0, 0);
  11. //获取GDAL驱动,PNG表示为用png驱动保存数据
  12. GDALDriver* pDriverSave = GetGDALDriverManager()->GetDriverByName("PNG");
  13. pDriverSave->CreateCopy("saved.png", poDataset2, TRUE, 0, 0, 0); //创建png文件
  14. std::cout << "png 文件保存成功" << std::endl;

4.4 关闭GDAL对象,并注销所有驱动

  1. GDALClose(poDataset);
  2. GDALClose(poDataset2);
  3. GDALClose(poDataset3);
  4. GDALDestroyDriverManager();

5、代码及效果

5.1 全部代码

  1. #include <iostream>
  2. #include <memory>
  3. #include <chrono>
  4. #include <fstream>
  5. #include <string>
  6. #include <iomanip>
  7. #include <opencv2/highgui.hpp>
  8. #include <opencv2/opencv.hpp>
  9. #include "gdal_priv.h"
  10. #include <gdal_alg_priv.h>
  11. #include <gdal.h>
  12. using namespace std;
  13. using namespace cv;
  14. //参考https://blog.csdn.net/ivan_ljf/article/details/9226463
  15. //计算trans中图片xy点的经纬度信息
  16. //adfGeoTransform的6个参数分别为左上角x坐标,水平分辨率,旋转参数,左上角y坐标,旋转参数,竖直分辨率,一般来说,旋转参数都为0
  17. bool Projection2ImageRowCol(double* adfGeoTransform, double dProjX, double dProjY, int& iCol, int& iRow)
  18. {
  19. try
  20. {
  21. double dTemp = adfGeoTransform[1] * adfGeoTransform[5] - adfGeoTransform[2] * adfGeoTransform[4];
  22. double dCol = 0.0, dRow = 0.0;
  23. dCol = (adfGeoTransform[5] * (dProjX - adfGeoTransform[0]) -
  24. adfGeoTransform[2] * (dProjY - adfGeoTransform[3])) / dTemp + 0.5;
  25. dRow = (adfGeoTransform[1] * (dProjY - adfGeoTransform[3]) -
  26. adfGeoTransform[4] * (dProjX - adfGeoTransform[0])) / dTemp + 0.5;
  27. iCol = int(dCol);
  28. iRow = int(dRow);
  29. return true;
  30. }
  31. catch (...)
  32. {
  33. return false;
  34. }
  35. }
  36. bool ImageRowCol2Projection(double* adfGeoTransform, int iCol, int iRow, double& dProjX, double& dProjY)
  37. {
  38. try
  39. {
  40. dProjX = adfGeoTransform[0] + adfGeoTransform[1] * iCol + adfGeoTransform[2] * iRow;
  41. dProjY = adfGeoTransform[3] + adfGeoTransform[4] * iCol + adfGeoTransform[5] * iRow;
  42. return true;
  43. }
  44. catch (...)
  45. {
  46. return false;
  47. }
  48. }
  49. int main() {
  50. GDALAllRegister();//注册所有的驱动
  51. CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); //设置支持中文路径和文件名
  52. //1、加载tif数据
  53. string file_path_name = "test.tif";
  54. //std::cout << "请输入图片路径:" << std::endl;
  55. //std::cin >> file_path_name;
  56. GDALDataset* poDataset = (GDALDataset*)GDALOpen(file_path_name.c_str(), GA_ReadOnly);//GA_Update和GA_ReadOnly两种模式
  57. if (poDataset == NULL)
  58. {
  59. std::cout << "指定的文件不能打开!" << std::endl;
  60. return 0;
  61. }
  62. //获取图像的尺寸
  63. int nImgSizeX = poDataset->GetRasterXSize();
  64. int nImgSizeY = poDataset->GetRasterYSize();
  65. std::cout << "ImageX = " << nImgSizeX << ", ImageY = " << nImgSizeY << std::endl;
  66. //获取图像的通道数(波段数量)
  67. int bandCount = poDataset->GetRasterCount();
  68. std::cout << "bandCount = " << bandCount << std::endl;
  69. //获取图像波段 在GDAL中波段数的起始数是1,而非0
  70. GDALRasterBand* poBand1 = poDataset->GetRasterBand(1);
  71. //GDAL中的数据类型 由此可知,每一个波段都可以有不同的数据类型
  72. /* 一共包含以下12种数据类型
  73. typedef enum {
  74. GDT_Unknown = 0,
  75. GDT_Byte = 1,
  76. GDT_UInt16 = 2,
  77. GDT_Int16 = 3,
  78. GDT_UInt32 = 4,
  79. GDT_Int32 = 5,GDT_UInt64,GDT_Int64
  80. GDT_Float32 = 6,
  81. GDT_Float64 = 7,
  82. GDT_CInt16 = 8,
  83. GDT_CInt32 = 9,GDT_CInt64
  84. GDT_CFloat32 = 10,
  85. GDT_CFloat64 = 11,
  86. GDT_TypeCount = 12
  87. } GDALDataType;
  88. */
  89. GDALDataType g_type = GDALDataType(poBand1->GetRasterDataType());
  90. std::cout << "g_type = " << g_type << std::endl;
  91. //获取坐标变换系数
  92. double trans[6] = { 0,1,0,0,0,1 };//定义为默认值,即x、y分辨率为1,其他信息为0
  93. CPLErr aaa = poDataset->GetGeoTransform(trans);
  94. trans[2] = 0.3;//修改x的旋转参数信息
  95. trans[4] = 0.1;//修改y的旋转参数信息
  96. //poDataset->SetGeoTransform(trans);//设置坐标变换系数
  97. std::cout << "trans = " << trans[0] << "," << trans[1] << "," << trans[2] << "," << trans[3] << "," << trans[4] << "," << trans[5] << std::endl;
  98. //像素坐标与投影坐标的换算
  99. double dProjX, dProjY;
  100. int iCol, iRow;
  101. iCol = 111;
  102. iRow = 111;
  103. ImageRowCol2Projection(trans, iCol, iRow, dProjX, dProjY);
  104. std::cout << "在trans中,像素坐标=》经纬度:" << iCol << "," << iRow << "====》" << dProjX << "," << dProjY << std::endl;
  105. Projection2ImageRowCol(trans, dProjX, dProjY, iCol, iRow);
  106. std::cout << "在trans中,经纬度=》像素坐标:" << dProjX << "," << dProjY << "====》" << iCol << "," << iRow << std::endl;
  107. //获取图像投影坐标系信息,
  108. std::string projs = poDataset->GetProjectionRef();
  109. //设置地理坐标系信息
  110. //poDataset->SetProjection(projs.c_str());
  111. std::cout << "projs = " << projs << std::endl;
  112. //读取gadl中第一个通道的数据到mat中 【通道数是从1开始的】
  113. //RasterIO参数列表的详细说明可以参考 https://blog.51cto.com/u_15469043/4903358
  114. /*从参数列表中是可以看到,GDAL是支持将数据分块读入的内存中的
  115. CPLErr GDALRasterBand::RasterIO ( GDALRWFlag eRWFlag,
  116. int nXOff,//x的起始点
  117. int nYOff,//y的起始点
  118. int nXSize,//读取窗口的宽
  119. int nYSize,//读取窗口的高
  120. void * pData,
  121. int nBufXSize,//与nXSize相同
  122. int nBufYSize,//与nYSize相同
  123. GDALDataType eBufType,
  124. int nPixelSpace,//通常默认为0
  125. int nLineSpace //通常默认为0
  126. )
  127. */
  128. //
  129. cv::Mat gdal_mat1(nImgSizeY, nImgSizeX, CV_8UC1, Scalar(0));
  130. cv::Mat gdal_mat2(nImgSizeY, nImgSizeX, CV_8UC1, Scalar(0));
  131. cv::Mat gdal_mat3(nImgSizeY, nImgSizeX, CV_8UC1, Scalar(0));
  132. poDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, 0, nImgSizeX, nImgSizeY, gdal_mat1.data, nImgSizeX, nImgSizeY, g_type, 0, 0);
  133. poDataset->GetRasterBand(2)->RasterIO(GF_Read, 0, 0, nImgSizeX, nImgSizeY, gdal_mat2.data, nImgSizeX, nImgSizeY, g_type, 0, 0);
  134. poDataset->GetRasterBand(3)->RasterIO(GF_Read, 0, 0, nImgSizeX, nImgSizeY, gdal_mat3.data, nImgSizeX, nImgSizeY, g_type, 0, 0);
  135. cv::Mat mg;
  136. cv::merge(vector<cv::Mat>{ gdal_mat3, gdal_mat2, gdal_mat1,}, mg);
  137. cv::imwrite("read_save.jpg", mg);
  138. /*
  139. //读取gadl中第一个通道的数据到指针中
  140. //void * malloc(size_t n):给指针分配相应的内存,并返回内存空间的首地址。当内存不再使用的时候,应使用free()函数将内存块释放掉。
  141. uint8_t* srcData = (uint8_t*)malloc(sizeof(uint8_t) * nImgSizeX * nImgSizeY);
  142. //void * memset (void * p,int c,size_t n):将p中的n个字节都赋值为c
  143. memset(srcData, 0, sizeof(uint8_t) * 1 * nImgSizeX * nImgSizeY);//为空间赋默认值0
  144. poDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, 0, nImgSizeX, nImgSizeY, srcData, nImgSizeX, nImgSizeY, g_type, 0, 0);
  145. */
  146. //-----------创建gdal对象 MEM追加,CreateCopy保存支持tif、png、jpg等格式-----
  147. int nImgSizeX2 = gdal_mat1.cols;
  148. int nImgSizeY2 = gdal_mat1.rows;
  149. //获取GDAL驱动,MEM表示为内存对象,可以快速的分块追加写入数据。MEM文件大小是和你的系统内存大小有关系,并不会存储到磁盘中。可用的驱动格式还有:BMP、JPEG、PNG、GTiff、GIF、HFA、BT、ECW、FITS、HDF4、EHdr。分别对应着不同的文件类型
  150. GDALDriver* pDriverMEM = GetGDALDriverManager()->GetDriverByName("MEM");
  151. int nBands = 1;
  152. //创建GDAL对象,只保存原图的一个通道
  153. //Create(const char * pszName,int nXSize, int nYSize, int nBands, GDALDataType eType, char** papszOptions)
  154. GDALDataset* poDataset2 = pDriverMEM->Create("", nImgSizeX2, nImgSizeY2, nBands, g_type, NULL);
  155. //将mat数据写入到GDALDataset中
  156. poDataset2->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, nImgSizeX2, nImgSizeY2, gdal_mat1.data, nImgSizeX2, nImgSizeY2, GDT_Byte, 0, 0);
  157. //获取GDAL驱动,PNG表示为用png驱动保存数据
  158. GDALDriver* pDriverSave = GetGDALDriverManager()->GetDriverByName("PNG");
  159. pDriverSave->CreateCopy("saved.png", poDataset2, TRUE, 0, 0, 0); //创建png文件
  160. std::cout << "png 文件保存成功" << std::endl;
  161. //-----------创建gdal对象 一次性写入,只支持tiff数据。PEN、JPEG等驱动没有实现相应的Create方法-----
  162. int nImgSizeX3 = gdal_mat1.cols;
  163. int nImgSizeY3 = gdal_mat1.rows;
  164. GDALDriver* pDriverMEM3 = GetGDALDriverManager()->GetDriverByName("GTiff");
  165. if (!pDriverMEM3) {
  166. fprintf(stderr, "get driver by name failed\n");
  167. return -1;
  168. }
  169. int nBands3 = 1;
  170. GDALDataset* poDataset3 = pDriverMEM3->Create("saved3.tif", nImgSizeX3, nImgSizeY3, nBands3, g_type, NULL);
  171. if (!poDataset3) {
  172. fprintf(stderr, "Create GDALDataset failed\n");
  173. return -1;
  174. }
  175. poDataset3->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, nImgSizeX3, nImgSizeY3, gdal_mat1.data, nImgSizeX3, nImgSizeY3, GDT_Byte, 0, 0);
  176. std::cout << "tif 文件保存成功" << std::endl;
  177. //关闭GDAL对象,并注销所有驱动
  178. GDALClose(poDataset);
  179. GDALClose(poDataset2);
  180. GDALClose(poDataset3);
  181. GDALDestroyDriverManager();
  182. return -1;
  183. }

5.2 运行结果

运行界面输出

 运行过程中的测试数据及保存结果

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/329869
推荐阅读
  

闽ICP备14008679号