使用GDAL实现常用图像格式(JPEG、PNG32、PNG24)之间的转换

主要思路

  • 使用GDAL库实现图像类型转换功能
  • 读取原始图像的数据,返回图像的宽、高、通道数量
  • 创建内存驱动器,将原始图像的数据写入到内存驱动器中
  • 使用CreateCopy接口,将内存驱动器的数据生成要求的jpg或者png图像
    • 读取和写入的时候,都是按通道从0 0位置开始一次性读取图像宽和高数量的像素。
    • 按照源图像的通道数量作为间隔拷贝原始数据到内存驱动器中。

参考网址

https://www.cnblogs.com/xiangism/p/5311314.html

https://blog.csdn.net/godenlove007/article/details/8864763

读取图像原始数据

	    bool ReadImageData( unsigned char **pImageData,int &nWidth,int &nHeight,int &nChannels,const QString& strFilePath )
		{
			GDALAllRegister();
			GDALDataset *poDataset = NULL;
	
			CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");
	
			poDataset=(GDALDataset*) GDALOpen(strFilePath.toLocal8Bit(),GA_ReadOnly);	
			if(poDataset == NULL)
			{
				//qDebug()<GetRasterXSize();
			nHeight = poDataset->GetRasterYSize();
			nChannels = poDataset->GetRasterCount();
	
			*pImageData = new unsigned char[nChannels * nWidth * nHeight];		
			ZeroMemory(*pImageData,nChannels * nWidth * nHeight);
	
			for (int i = 1; i <= nChannels; ++ i)
			{
				unsigned char *pImageOffset = *pImageData + i - 1;
				GDALRasterBand* pBand = poDataset->GetRasterBand(i);
	
				pBand->RasterIO(
					GF_Read,
					0,0,			
					nWidth,nHeight,	
					pImageOffset,	
					nWidth,nHeight,	
					GDT_Byte,		
					nChannels,				
					0);				
			}
	
			GDALClose(poDataset);
			return true;
		}

创建指定格式的图像

  • GetDriverType就是根据目标文件后缀名获取对应的驱动器类型:比如".jpg"对应"JPEG"。

  • 创建完成后注意数据集的释放。

      	bool WriteImageData(const QString& strDestFilePath,unsigned char* pImageData,int nWidth,int nHeight,int nChannels,int nNewChannels)
      	{
      		CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");
      
      		GDALAllRegister();
      
      		QString strType;
      		GetDriverType(strDestFilePath,strType);
      
      		GDALDriver *pMemDriver = NULL;
      		pMemDriver = GetGDALDriverManager()->GetDriverByName("MEM");
      		if( pMemDriver == NULL ) { return false; }
      
      		GDALDataset * pMemDataSet = pMemDriver->Create("",nWidth,nHeight,nNewChannels,GDT_Byte,NULL);
      		GDALRasterBand *pBand = NULL;
      
      		for (int i = 1; i <= nNewChannels; i++)
      		{
      			if (i==nNewChannels && nNewChannels >nChannels)
      			{
      				unsigned char *pTempImageData = new unsigned char[nNewChannels*nWidth*nHeight];
      				memset(pTempImageData,0xFE,nNewChannels*nWidth*nHeight);
      
      				pBand = pMemDataSet->GetRasterBand(i);
      				pBand->RasterIO(GF_Write, 
      					0, 
      					0, 
      					nWidth, 
      					nHeight, 
      					pTempImageData, 
      					nWidth, 
      					nHeight, 
      					GDT_Byte, 
      					nNewChannels, 
      					0); 
      			}
      			else
      			{
      				pBand = pMemDataSet->GetRasterBand(i);
      				pBand->RasterIO(GF_Write, 
      					0, 
      					0, 
      					nWidth, 
      					nHeight, 
      					pImageData+i-1 , 
      					nWidth, 
      					nHeight, 
      					GDT_Byte, 
      					nChannels, 
      					0); 
      			}
      		}
      
      		GDALDriver *pDstDriver = NULL;
      		pDstDriver = (GDALDriver *)GDALGetDriverByName(strType.toStdString().c_str());
      		if (pDstDriver == NULL)
      		{ 
      			GDALClose(pMemDataSet); 
      
      			return false;
      		}
      
      		GDALDataset * pDataSet = pDstDriver->CreateCopy(strDestFilePath.toLocal8Bit(),pMemDataSet,FALSE, NULL, NULL, NULL);
      		if (pDataSet == NULL)
      		{
      			GDALClose(pMemDataSet); 
      
      			return false;
      		}
      
      		GDALClose(pDataSet); 
      		GDALClose(pMemDataSet); 
      
      		return true; 
      	}
    

你可能感兴趣的:(GDAL,GDAL,JPEG,PNG32,PNG24,转换)