头文件:
#ifndef IMAGETHUMB_H
#define IMAGETHUMB_H
#pragma once
#include <gdal_priv.h>
//生成单波段灰度缩略图
bool CreateThumbnail( const char* input , const char* output , int bandID , float scale);
//生成RGB彩色缩略图
bool CreateThumbnail( const char* input , const char* output , int redBand,int greenBand, int blueBand, float scale);
#endif
源文件:
#include "ImageThumb.h"
#include "gdal_pam.h"
bool CreateThumbnail( const char* input , const char* output , int bandID , float scale)
{
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO"); //设置支持中文路径
GDALDataset *pDataset = (GDALDataset *) GDALOpen( input, GA_ReadOnly );
if( pDataset == NULL )
return false;
int nSamples = ((GDALDataset *)pDataset)->GetRasterXSize();
int nLines = ((GDALDataset *)pDataset)->GetRasterYSize();
int nBands = ((GDALDataset *)pDataset)->GetRasterCount();
if(bandID > nBands)
{
GDALClose( (GDALDatasetH) pDataset );
return false;
}
int i , j ;
float *pBuffer = new float[ nSamples ];
//查找该波段的最值
GDALRasterBand *pBandRead = ((GDALDataset *)pDataset)->GetRasterBand( bandID );
float minV,maxV;
for ( i = 0 ; i < nLines ; i++ )
{
if( pBandRead->RasterIO(GF_Read,0,i,nSamples,1,pBuffer,nSamples,1,GDT_Float32,0,0 ) != CE_None )
{
cout<<"Fail to read image!"<<endl;
delete[] pBuffer;
GDALClose( (GDALDatasetH) pDataset );
return false;
}
for( j = 0 ; j < nSamples ; j++ )
{
if ( ( i == 0 ) && ( j == 0 ) ) maxV = minV = pBuffer[ 0 ];
if( pBuffer[ j ] < minV ) minV = pBuffer[ j ];
if( pBuffer[ j ] > maxV ) maxV = pBuffer[ j ];
}
}
//打开写入图像
GDALDriver * pDriver = (GDALDriver*)GDALGetDriverByName( "BMP" );
if( pDriver == NULL )
{
cout<<"Fail to create bmp fiel driver!"<<endl;
delete[] pBuffer;
GDALClose( (GDALDatasetH) pDataset );
return false;
}
int stepSize = int( 1.0f / scale );
int outSample = int(nSamples / stepSize);
int outLine = int(nLines / stepSize);
char tmpFile[ 512 ];
strcpy( tmpFile , output );
strcat( tmpFile , ".bmp" );
GDALDataset* pDSOut = pDriver->Create( tmpFile,outSample,outLine,1,GDT_Byte,NULL);
if( pDSOut == NULL )
{
delete[] pBuffer;
GDALClose( (GDALDatasetH) pDataset );
return false;
}
unsigned char* pBufferOut = new unsigned char[ outSample ];//输出缓存
GDALRasterBand *pBandWrite = ((GDALDataset *)pDSOut)->GetRasterBand( 1 );
int offset;
int offsetY = 0;
//写入图像
for ( i = 0 ; i < nLines ; i+= stepSize )
{
if( pBandRead->RasterIO(GF_Read,0,i,nSamples,1,pBuffer,nSamples,1,GDT_Float32,0,0 ) != CE_None )
{
cout<<"error read image!"<<endl;
delete[] pBuffer;
delete[] pBufferOut;
GDALClose( (GDALDatasetH) pDataset );
GDALClose( (GDALDatasetH) pDSOut );
return false;
}
offset = 0;
for( j = 0 ; j < nSamples ; j+= stepSize )
{
pBufferOut[ offset ] = (unsigned char)(( pBuffer[ j ] - minV ) * 256 / ( maxV - minV + 1 ));
offset++;
}
pBandWrite->WriteBlock( 0 , offsetY , pBufferOut );
offsetY++;
}
delete[] pBuffer;
delete[] pBufferOut;
GDALDriver * poDriver = GetGDALDriverManager()->GetDriverByName("JPEG");
if( poDriver == NULL )
{
GDALClose( (GDALDatasetH) pDataset );
GDALClose( (GDALDatasetH) pDSOut );
return false;
}
GDALDataset * poDataset3=poDriver->CreateCopy(output,pDSOut,false,NULL,NULL,NULL);
//reject to save ".aux.xml" file
GDALPamDataset *pamDs=dynamic_cast<GDALPamDataset*>(poDataset3);
if(pamDs)
{
int pamFlags=pamDs->GetPamFlags();
pamFlags|=GPF_NOSAVE;
pamDs->SetPamFlags(pamFlags);
}
if( pDSOut != NULL )
GDALClose( (GDALDatasetH) pDSOut );
pDriver->Delete( tmpFile );
if( pDataset != NULL )
GDALClose( (GDALDatasetH) pDataset );
if( poDataset3 != NULL )
GDALClose( (GDALDatasetH) poDataset3 );
return true;
}
bool CreateThumbnail( const char* input , const char* output , int redBand,int greenBand, int blueBand, float scale)
{
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");
GDALDataset *pDataset = (GDALDataset *) GDALOpen( input, GA_ReadOnly );
if( pDataset == NULL )
return false;
int nSamples = ((GDALDataset *)pDataset)->GetRasterXSize();
int nLines = ((GDALDataset *)pDataset)->GetRasterYSize();
int nBands = ((GDALDataset *)pDataset)->GetRasterCount();
int rgbBand[] = {redBand,greenBand,blueBand};
int i,j,k;
for(i=0;i<3;i++)
{
if(rgbBand[i] > nBands)
{
GDALClose( (GDALDatasetH) pDataset );
return false;
}
}
//统计各波段的最大值和最小值
float minV[3]={0},maxV[3]={0};
float *pBuffer = new float[ nSamples ];
for( k=0 ; k<3 ; k++ )
{
GDALRasterBand *pBandRead = ((GDALDataset *)pDataset)->GetRasterBand( rgbBand[k] );
for ( i = 0 ; i < nLines ; i++ )
{
if( pBandRead->RasterIO(GF_Read,0,i,nSamples,1,pBuffer,nSamples,1,GDT_Float32,0,0 ) != CE_None )
{
cout<<"Fail to read image!"<<endl;
delete[] pBuffer;
GDALClose( (GDALDatasetH) pDataset );
return false;
}
for( j = 0 ; j < nSamples ; j++ )
{
if ( ( i == 0 ) && ( j == 0 ) ) maxV[k] = minV[k] = pBuffer[ 0 ];
if( pBuffer[ j ] < minV[k] ) minV[k] = pBuffer[ j ];
if( pBuffer[ j ] > maxV[k] ) maxV[k] = pBuffer[ j ];
}
}
}
//打开写入图像
GDALDriver * pDriver = (GDALDriver*)GDALGetDriverByName( "BMP" );
if( pDriver == NULL )
{
cout<<"Fail to create bmp fiel driver!"<<endl;
delete[] pBuffer;
GDALClose( (GDALDatasetH) pDataset );
return false;
}
int stepSize = int( 1.0f / scale );
int outSample = int(nSamples / stepSize) + ((nSamples % stepSize) == 0 ? 0:1);
int outLine = int(nLines / stepSize) + ((nLines % stepSize) == 0 ? 0:1 );
char tmpFile[ 512 ];
strcpy( tmpFile , output );
strcat( tmpFile , ".bmp" );
GDALDataset* pDSOut = pDriver->Create( tmpFile,outSample,outLine,3,GDT_Byte,NULL);
if( pDSOut == NULL )
{
delete[] pBuffer;
GDALClose( (GDALDatasetH) pDataset );
return false;
}
//写入图像
unsigned char* pBufferOut = new unsigned char[ outSample ];//输出缓存
for( k=0 ; k<3 ; k++ )
{
GDALRasterBand *pBandWrite = ((GDALDataset *)pDSOut)->GetRasterBand( k +1 );
GDALRasterBand *pBandRead = ((GDALDataset *)pDataset)->GetRasterBand( rgbBand[k] );
int offset;
int offsetY = 0;
for ( i = 0 ; i < nLines ; i+= stepSize )
{
if( pBandRead->RasterIO(GF_Read,0,i,nSamples,1,pBuffer,nSamples,1,GDT_Float32,0,0 ) != CE_None )
{
cout<<"error read image!"<<endl;
delete[] pBuffer;
delete[] pBufferOut;
GDALClose( (GDALDatasetH) pDataset );
GDALClose( (GDALDatasetH) pDSOut );
return false;
}
offset = 0;
for( j = 0 ; j < nSamples ; j+= stepSize )
{
pBufferOut[ offset ] = (unsigned char)(( pBuffer[ j ] - minV[k] ) * 256 / ( maxV[k] - minV[k] + 1 ));
offset++;
}
pBandWrite->WriteBlock( 0 , offsetY , pBufferOut );
offsetY++;
}
}
delete[] pBuffer;
delete[] pBufferOut;
GDALDriver * poDriver = GetGDALDriverManager()->GetDriverByName("JPEG");
if( poDriver == NULL )
{
GDALClose( (GDALDatasetH) pDataset );
GDALClose( (GDALDatasetH) pDSOut );
return false;
}
GDALDataset * poDataset3=poDriver->CreateCopy(output,pDSOut,false,NULL,NULL,NULL);
//reject to save ".aux.xml" file
GDALPamDataset *pamDs=dynamic_cast<GDALPamDataset*>(poDataset3);
if(pamDs)
{
int pamFlags=pamDs->GetPamFlags();
pamFlags|=GPF_NOSAVE;
pamDs->SetPamFlags(pamFlags);
}
if( pDSOut != NULL )
GDALClose( (GDALDatasetH) pDSOut );
pDriver->Delete( tmpFile );
if( pDataset != NULL )
GDALClose( (GDALDatasetH) pDataset );
if( poDataset3 != NULL )
GDALClose( (GDALDatasetH) poDataset3 );
return true;
}
用法:
char* imageFileName = "E:\\Project\\RSData\\test1.tiff";
CreateThumbnail( imageFileName , "E:\\Project\\RSData\\test1_1.jpg" , 10 , 1.0f );
CreateThumbnail( imageFileName , "E:\\Project\\RSData\\test1_2.jpg" , 44 , 23 , 13 , 1.0f);
CreateThumbnail( imageFileName , "E:\\Project\\RSData\\test1_3.jpg" , 10 , 0.5f );
CreateThumbnail( imageFileName , "E:\\Project\\RSData\\test1_4.jpg", 44 , 23 , 13 , 0.5f);