GDAL生成灰度和彩色缩略图

18 篇文章 0 订阅
6 篇文章 0 订阅

头文件:

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



  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深蓝静音

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值