您的位置:首页 > 其它

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

2019-01-02 18:05 776 查看

主要思路

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

参考网址

https://www.geek-share.com/detail/2670388402.html

https://www.geek-share.com/detail/2578149743.html

读取图像原始数据

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()<<QString::fromLocal8Bit("%1 GDAL打开失败").arg(strFilePath);
GDALClose(poDataset);
return false;
}

nWidth = poDataset->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;
    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: