GDAL生成灰度和彩色縮略圖

頭文件:

#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);



發佈了59 篇原創文章 · 獲贊 58 · 訪問量 40萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章