关键代码:主要流程是先将16位的像素指针强制转成uint16_t*,方便进行指针运算,因为原始的指针是char*。
注意:指针移动的字节长度等与指针所指类型的字节长度(原来指针类型强制转换这么有用)
然后通过uint16_t获取16位像素的值,再赋值给8位像素值。
通过指针运算进行取值,不同类型的指针移动长度不一样,同时取值时根据指针类型进行取值。
if (eDT ==GDT_UInt16)
{
// 申请所有数据所需要的缓存,如果图像太大应该用分块处理
char *pDataBuff =(char *) malloc(iDstWidth*iDstHeight*iBandCount*eDT);
int res=pSrcDS->RasterIO(GF_Read, iStartX, iStartY, iDstWidth, iDstHeight,
pDataBuff, iDstWidth, iDstHeight, eDT, iBandCount, pBandMap, 0, 0, 0);
//转化为8位--lj (指针操作真复杂,用会了真方便!)
char *pDataBuff8 =(char *) malloc(iDstWidth*iDstHeight*iBandCount);
uint16_t* pDataBuff16=(uint16_t*)pDataBuff;
for (int w=0;w
for (int h=0;h
for (int b=0;b
//此处可以增加灰度拉伸的代码,本程序只是针对在16位图像上像素值是0-255的图像
*(pDataBuff8+w*iDstHeight*iBandCount+h*iBandCount+b)=*(pDataBuff16+w*iDstHeight*iBandCount+h*iBandCount+b);
}
}
}
res=pDstDS->RasterIO(GF_Write, 0, 0, iDstWidth, iDstHeight,
pDataBuff8, iDstWidth, iDstHeight, GDT_Byte, iBandCount, pBandMap, 0, 0, 0);
//delete[] pDataBuff;
free( pDataBuff);
free( pDataBuff8);
}
完整代码如下:
void Image18bitTo8bit(const char* pszSrcFile, const char* pszDstFile,const char* pszFormat)
{
//支持中文路径
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");
GDALAllRegister();
GDALDataset* pSrcDS=(GDALDataset*)GDALOpen(pszSrcFile, GA_ReadOnly);
GDALDataType eDT = pSrcDS->GetRasterBand(1)->GetRasterDataType();
//默认波段为3
int iBandCount = pSrcDS->GetRasterCount();
if (iBandCount>=3)
iBandCount = 3;
// 根据裁切范围确定裁切后的图像宽高
int iDstWidth = pSrcDS->GetRasterXSize();
int iDstHeight = pSrcDS->GetRasterYSize();
int iStartX=0, iStartY=0;
double adfGeoTransform[6] = {0};
pSrcDS->GetGeoTransform(adfGeoTransform);
// 创建输出文件并设置空间参考和坐标信息
GDALDriver* poDriver = (GDALDriver *)GDALGetDriverByName(pszFormat);
GDALDataset *pDstDS = poDriver->Create(pszDstFile, iDstWidth, iDstHeight, iBandCount, GDT_Byte, NULL);
pDstDS->SetGeoTransform(adfGeoTransform);
pDstDS->SetProjection(pSrcDS->GetProjectionRef());
int *pBandMap = new int[iBandCount];
for (int i=0; i
if (eDT == GDT_Byte) // 如果是8bit图像
{
// 申请所有数据所需要的缓存,如果图像太大应该用分块处理
//char *pDataBuff =new char[iDstWidth*iDstHeight*iBandCount];
char *pDataBuff =(char *) malloc(iDstWidth*iDstHeight*iBandCount);
int res=pSrcDS->RasterIO(GF_Read, iStartX, iStartY, iDstWidth, iDstHeight,
pDataBuff, iDstWidth, iDstHeight, eDT, iBandCount, pBandMap, 0, 0, 0);
res=pDstDS->RasterIO(GF_Write, 0, 0, iDstWidth, iDstHeight,
pDataBuff, iDstWidth, iDstHeight, eDT, iBandCount, pBandMap, 0, 0, 0);
//delete[] pDataBuff;
free( pDataBuff);
}
else if (eDT ==GDT_UInt16)
{
// 申请所有数据所需要的缓存,如果图像太大应该用分块处理
char *pDataBuff =(char *) malloc(iDstWidth*iDstHeight*iBandCount*eDT);
int res=pSrcDS->RasterIO(GF_Read, iStartX, iStartY, iDstWidth, iDstHeight,
pDataBuff, iDstWidth, iDstHeight, eDT, iBandCount, pBandMap, 0, 0, 0);
//转化为8位--lj (指针操作真复杂,用会了真方便!)
char *pDataBuff8 =(char *) malloc(iDstWidth*iDstHeight*iBandCount);
uint16_t* pDataBuff16=(uint16_t*)pDataBuff;
for (int w=0;w
for (int h=0;h
for (int b=0;b
//此处可以增加灰度拉伸的代码,本程序只是针对在16位图像上像素值是0-255的图像
*(pDataBuff8+w*iDstHeight*iBandCount+h*iBandCount+b)=*(pDataBuff16+w*iDstHeight*iBandCount+h*iBandCount+b);
}
}
}
res=pDstDS->RasterIO(GF_Write, 0, 0, iDstWidth, iDstHeight,
pDataBuff8, iDstWidth, iDstHeight, GDT_Byte, iBandCount, pBandMap, 0, 0, 0);
//delete[] pDataBuff;
free( pDataBuff);
free( pDataBuff8);
}
delete(pBandMap);
GDALClose((GDALDatasetH)pSrcDS);
GDALClose((GDALDatasetH)pDstDS);
return ;
}