基于GDAL的tiff数据类型格式转化方法(实现将各类数据统一转化为unsigned char,即GByte)
//调用方法
//convertToGByteTiff(“原始数据.tif”,"转换后数据.tif");
#include "gdal_priv.h"
#include "ogrsf_frmts.h"
using namespace std;
void convertToGByteTiff(std::string initialTiff, std::string newTiff)
{
GDALAllRegister();
//设置支持中文路径
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
const char * pszFile = initialTiff.c_str();
GDALDataset *poDataset = (GDALDataset*)GDALOpen(pszFile, GA_ReadOnly);//使用只读方式打开图像
if (!poDataset)
{
printf("File: %s不能打开!\n", pszFile);
}
//仿射参数
double padfTransform0[6];
if (poDataset->GetGeoTransform(padfTransform0) == CE_Failure)
{
printf("获取仿射变换参数失败");
}
int iImgSizeX0 = poDataset->GetRasterXSize();
int iImgSizeY0 = poDataset->GetRasterYSize();
int nCount = poDataset->GetRasterCount(); //影像的波段数
GDALDataType gdal_data_type = poDataset->GetRasterBand(1)->GetRasterDataType();//获取栅格类型
double dNodata= poDataset->GetRasterBand(1)->GetNoDataValue();//获取空值对应大小
//设置各类型数组
short int *pSI_afScanblock1=NULL;
unsigned short *pUS_afScanblock1 = NULL;
unsigned long *pUL_afScanblock1 = NULL;
long *pL_afScanblock1 = NULL;
float *pF_afScanblock1 = NULL;
double *pD_afScanblock1 = NULL;
unsigned char *_pNewValue = new unsigned char[iImgSizeX0*iImgSizeY0];
switch (gdal_data_type)
{
case GDT_Byte:
{
//当前类型正确,不用转换
return;
break;
}
case GDT_UInt16:
{
pUS_afScanblock1 = new unsigned short [iImgSizeX0*iImgSizeY0 * 1];
poDataset->RasterIO(GF_Read, 0, 0, iImgSizeX0, iImgSizeY0, pUS_afScanblock1, iImgSizeX0, iImgSizeY0, gdal_data_type, 1, 0, 0, 0, 0);
for (int i = 0; i < iImgSizeX0*iImgSizeY0; i++)
_pNewValue[i] = (unsigned char)pUS_afScanblock1[i];
break;
}
case GDT_Int16:
{
pSI_afScanblock1 = new short int[iImgSizeX0*iImgSizeY0 * 1];
poDataset->RasterIO(GF_Read, 0, 0, iImgSizeX0, iImgSizeY0, pSI_afScanblock1, iImgSizeX0, iImgSizeY0, gdal_data_type, 1, 0, 0, 0, 0);
for (int i = 0; i < iImgSizeX0*iImgSizeY0; i++)
_pNewValue[i] = (unsigned char)pSI_afScanblock1[i];
break;
}
case GDT_UInt32:
{
pUL_afScanblock1 = new unsigned long[iImgSizeX0*iImgSizeY0 * 1];
poDataset->RasterIO(GF_Read, 0, 0, iImgSizeX0, iImgSizeY0, pUL_afScanblock1, iImgSizeX0, iImgSizeY0, gdal_data_type, 1, 0, 0, 0, 0);
for (int i = 0; i < iImgSizeX0*iImgSizeY0; i++)
_pNewValue[i] = (unsigned char)pUL_afScanblock1[i];
break;
}
case GDT_Int32:
{
pL_afScanblock1 = new long[iImgSizeX0*iImgSizeY0 * 1];
poDataset->RasterIO(GF_Read, 0, 0, iImgSizeX0, iImgSizeY0, pL_afScanblock1, iImgSizeX0, iImgSizeY0, gdal_data_type, 1, 0, 0, 0, 0);
for (int i = 0; i < iImgSizeX0*iImgSizeY0; i++)
_pNewValue[i] = (unsigned char)pL_afScanblock1[i];
break;
}
case GDT_Float32:
{
pF_afScanblock1 = new float[iImgSizeX0*iImgSizeY0 * 1];
poDataset->RasterIO(GF_Read, 0, 0, iImgSizeX0, iImgSizeY0, pF_afScanblock1, iImgSizeX0, iImgSizeY0, gdal_data_type, 1, 0, 0, 0, 0);
for (int i = 0; i < iImgSizeX0*iImgSizeY0; i++)
_pNewValue[i] = (unsigned char)pF_afScanblock1[i];
break;
}
case GDT_Float64:
{
pD_afScanblock1 = new double[iImgSizeX0*iImgSizeY0 * 1];
poDataset->RasterIO(GF_Read, 0, 0, iImgSizeX0, iImgSizeY0, pD_afScanblock1, iImgSizeX0, iImgSizeY0, gdal_data_type, 1, 0, 0, 0, 0);
for (int i = 0; i < iImgSizeX0*iImgSizeY0; i++)
_pNewValue[i] = (unsigned char)pD_afScanblock1[i];
break;
}
default: break;
}
//写入新的tif
int pBandMap[3] = { 1,2,3 };//定义波段排序顺序
const char* pszDstFilename = newTiff.c_str();
GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff");
GDALDataset* poDstDS = poDriver->Create(pszDstFilename, iImgSizeX0, iImgSizeY0, nCount, GDT_Byte, NULL);
poDstDS->SetProjection(poDataset->GetProjectionRef());//给它设置投影
poDstDS->SetGeoTransform(padfTransform0);//给设置空间转换的六参数
poDstDS->GetRasterBand(1)->SetNoDataValue(dNodata);//将空值设置为“无数据值”
//保存影像
poDstDS->RasterIO(GF_Write, 0, 0, iImgSizeX0, iImgSizeY0, _pNewValue, iImgSizeX0, iImgSizeY0, GDT_Byte, nCount, pBandMap, 0, 0, 0);
//保存单波段
poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, iImgSizeX0, iImgSizeY0, _pNewValue, iImgSizeX0, iImgSizeY0, GDT_Byte, 0, 0);
//释放内存
GDALClose(poDstDS);
GDALClose(poDataset);
delete[]pSI_afScanblock1;
delete[]pUS_afScanblock1;
delete[]pUL_afScanblock1;
delete[]pL_afScanblock1;
delete[]pF_afScanblock1;
delete[]pD_afScanblock1;
delete[]_pNewValue;
}