GDAL-based tif data type format conversion method (converted to unsigned char, i.e. GByte)

GDAL-based tiff data type format conversion method (to achieve unified conversion of various types of data into unsigned char, i.e. 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;
}

Guess you like

Origin blog.csdn.net/HeyLoong/article/details/120688552