本博客为原创内容,未经博主允许禁止转载,商用,谢谢。
一、前言
关于GDAL与openCV间的数据格式转换,在我之前的博客中已有简要说明,这里,由于最近工作上经常用到openCV里的函数进行图像处理,所以写了一个程序,进一步对这两个开源库进行连接。
除了格式转换外,该类还支持数据的分块读入与写出。
二、代码
所有功能在一个GDALOPENCV类中完成,其头文件如下:
////////////////////////////////////////////////////////////////////// ////////////完成GDAL文件与OpenCV的文件读写转换//////////////// //////////////////////支持数据分块读写//////////////////////////////// ///////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// #pragma once #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <gdal_priv.h> #include <vector> #include <string> #include <math.h> #include <iostream> /***********************************************************/ // GCDataType:GDAL和OpenCV数据类型转换的中间格式 // GC_Byte ======= GDT_Byte ======= CV_8U ======= unsigned char // GC_UInt16 ======= GDT_UInt16 ======= CV_16U ======= unsigned short // GC_Int16 ======= GDT_Int16 ======= CV_16S ======= short int // GC_UInt32 ======= GDT_UInt32 ======= 缺失 ======= unsigned long // GC_Int32 ======= GDT_Int32 ======= CV_32S ======= long // GC_Float32======= GDT_Float32======= CV_32F ======= float // GC_Float64======= GDT_Float64======= CV_64F ======= double /***********************************************************/ typedef enum{ GC_Byte = 0, GC_UInt16 = 1, GC_Int16 = 2, GC_UInt32 = 3, GC_Int32 = 4, GC_Float32 = 5, GC_Float64 = 6, GC_ERRType = 7 } GCDataType; class GDALOpenCV { /***********************************************************/ // PatchIndex:存储具体影像分块信息 // iPatch 分类表:1----两个边界重合 2----三个边界重合 3----四个边界重合 // 11 12 13 14 21 22 23 24 31 // ======================= // 11 = 21 = 12 // ======================= // 24 = 31 = 22 // ======================= // 14 = 23 = 13 // ======================= /***********************************************************/ typedef struct { int iPatch; // 第几类 int row_begin; // 影像中起始行 int col_begin; // 影像中起始列 int width; // 影像块的宽度 int heigth; // 影像块的高度 } PatchIndex; public: GDALOpenCV(const std::string fileName); // 唯一构造函数 ~GDALOpenCV(void); // 析构函数 public: void Initialization(); // 初始化 实际上为获取影像格式; cv::Size SetPatchSize(const int r,const int c) // 设置分块大小 { m_patchSize.width = c; m_patchSize.height = r; return m_patchSize; }; void SetOverlappedPixel(const int num) { m_overlappedPixel = num; }; bool GDAL2Mat(cv::Mat &img); // 影像读取为Mat格式 不分块 bool Mat2File(const std::string outFileName,cv::Mat &img,const int flag = 1); // Mat文件输出为影像 // flag = 默认为1 输出TIFF 另外还支持ENVI 和 ARDAS数据格式 int GetImgToPatchNum(); // 返回影像分块数 和 获取影像分块信息 void GetROIFromPatchIndex(const int,cv::Mat &); // 获取对应块编号的影像 bool SetROIMatToFileByIndex(const std::string outFile,cv::Mat &img, const int index,const int flag = 1); // 影像分块写入 有待改进 具体细节有点商榷 GCDataType GDALType2GCType(const GDALDataType ty); // GDAL Type ==========> GDALOpenCV Type GDALDataType GCType2GDALType(const GCDataType ty); // GDALOpenCV Type ==========> GDAL Type GCDataType OPenCVType2GCType(const int ty); // OPenCV Type ==========> GDALOpenCV Type int GCType2OPenCVType(const GCDataType ty); // GDALOpenCV Type ==========> OPenCV Type private: void* AllocateMemory(const GCDataType lDataType,const long long lSize); // 智能分配内存 void* SetMemCopy(void *dst,const void *src,const GCDataType lDataType,const long long lSize); public: GCDataType m_dataType; // 数据类型 int m_imgWidth; // 影像宽度 列数 int m_imgHeigth; // 影像高度 行数 int m_bandNum; // 影像波段数 private: //GDALDataType m_gdalType; GDALDataset *m_poDataSet; // 数据驱动集 GDALDataset *m_outPoDataSet; cv::Size m_patchSize;// 分块图像大小 //std::string m_fileName; // 文件名 打开 cv::vector<PatchIndex> *m_patchIndex;//分块标识 int m_overlappedPixel; }; ////////////////////////////////////////////////////////// // 使用说明: ///////////////////////////////////////////////////////// // GDALOpenCV gdalOpenCV(fileName); // gdalOpenCV.Initialization();
cpp文件如下:
#include "GDALOpenCV.h" GDALOpenCV::GDALOpenCV(const std::string fileName) { m_poDataSet = NULL; GDALAllRegister(); m_poDataSet = (GDALDataset*)GDALOpen(fileName.c_str(),GA_ReadOnly); m_outPoDataSet = NULL; } GDALOpenCV::~GDALOpenCV(void) { if(m_poDataSet!=NULL) GDALClose((GDALDatasetH)m_poDataSet); if(m_outPoDataSet!=NULL) GDALClose((GDALDatasetH)m_outPoDataSet); m_patchIndex->clear(); delete m_patchIndex; m_patchIndex = NULL; } void GDALOpenCV::Initialization() { if(!m_poDataSet) return; m_imgHeigth= m_poDataSet->GetRasterYSize(); // 影像行 m_imgWidth = m_poDataSet->GetRasterXSize(); // 影像列 m_bandNum = m_poDataSet->GetRasterCount(); // 影像波段数 m_overlappedPixel = -1; // 重复像素个数 GDALRasterBand *pBand = m_poDataSet->GetRasterBand(1); GDALDataType gdalTy = pBand->GetRasterDataType(); m_dataType = GDALType2GCType(gdalTy); m_patchSize.width = m_imgWidth; m_patchSize.height = m_imgHeigth; m_patchIndex = new std::vector<PatchIndex>(1); PatchIndex tmp = {1,0,0,m_imgWidth,m_imgHeigth}; m_patchIndex->at(0) = tmp; } bool GDALOpenCV::GDAL2Mat(cv::Mat &img) { if(!m_poDataSet) return false; GDALRasterBand *pBand = NULL; // 波段 void *pafBuffer = AllocateMemory(m_dataType,m_imgHeigth*m_imgWidth); // 开辟内存 std::vector<cv::Mat> *imgMat = new std::vector<cv::Mat>(m_bandNum); // 存储各波段 cv::Mat *tmpMat = NULL; // 临时存储一个波段 int iBand = 0; // 波段标记 while(iBand<m_bandNum) { pBand = m_poDataSet->GetRasterBand(++iBand); pBand->RasterIO(GF_Read,0,0,m_imgWidth,m_imgHeigth,pafBuffer,m_imgWidth, m_imgHeigth,GCType2GDALType(m_dataType),0,0); tmpMat = new cv::Mat(m_imgHeigth,m_imgWidth,GCType2OPenCVType(m_dataType),pafBuffer); imgMat->at(iBand-1) = (*tmpMat).clone(); delete tmpMat; tmpMat = NULL; } cv::merge(*imgMat,img); // 内存管理 delete pafBuffer; pafBuffer = NULL; imgMat->clear(); delete imgMat; imgMat = NULL; return true; } bool GDALOpenCV::Mat2File( const std::string outFileName,cv::Mat &img, const int flag /*= 1*/ ) { if(img.empty()) return false; const int nBandCount=img.channels(); const int nImgSizeX=img.cols; const int nImgSizeY=img.rows; std::vector<cv::Mat> *imgMat = new std::vector<cv::Mat>(nBandCount); cv::split(img,*imgMat); GDALAllRegister(); //GDALDataset *poDataset; //GDAL数据集 GDALDriver *poDriver; //驱动,用于创建新的文件 //////////////////////////////// ///flag:1 ====》TIFF /// 2 ====》HFA /// 3 ====》ENVI std::string pszFormat; //存储数据类型 switch (flag) { case 1: pszFormat = "GTiff"; break; case 2: pszFormat = "HFA"; break; case 3: pszFormat = "ENVI"; break; default: return 0; } int OPenCVty = imgMat->at(0).type(); GCDataType GCty = OPenCVType2GCType(OPenCVty); poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat.c_str()); if(poDriver == NULL) return 0; if(m_outPoDataSet == NULL) { m_outPoDataSet=poDriver->Create(outFileName.c_str(),nImgSizeX,nImgSizeY,nBandCount, GCType2GDALType(GCty),NULL); m_outPoDataSet->SetProjection(m_poDataSet->GetProjectionRef()); double dGeotransform[6]; m_poDataSet->GetGeoTransform(dGeotransform); m_outPoDataSet->SetGeoTransform(dGeotransform); } // 循环写入文件 GDALRasterBand *pBand = NULL; void *ppafScan = AllocateMemory(GCty,nImgSizeX*nImgSizeY); int n1 = nImgSizeY; int nc = nImgSizeX; cv::Mat tmpMat; for(int i = 1;i<=nBandCount;i++) { pBand = m_outPoDataSet->GetRasterBand(i); tmpMat = imgMat->at(i-1); if(tmpMat.isContinuous()) SetMemCopy(ppafScan,(void*)tmpMat.ptr(0),GCty,nImgSizeX*nImgSizeY); else return false; CPLErr err = pBand->RasterIO(GF_Write,0,0,nImgSizeX,nImgSizeY,ppafScan, nImgSizeX,nImgSizeY,GCType2GDALType(GCty),0,0); } delete ppafScan; ppafScan = NULL; imgMat->clear();delete imgMat;imgMat = NULL; return 1; } int GDALOpenCV::GetImgToPatchNum() { if(m_patchSize.width >= m_imgWidth || m_patchSize.height >= m_imgHeigth) return 1; if(m_overlappedPixel == -1) return 1; ////////////////分块核心代码///////////////////// //////////////分块数确定//////////////////////// int rPatchNum = cvCeil((m_imgHeigth*1.0 -m_patchSize.height)/(m_patchSize.height - m_overlappedPixel)) + 1; int cPatchNum = cvCeil((m_imgWidth*1.0 - m_patchSize.width)/(m_patchSize.width - m_overlappedPixel)) +1; PatchIndex tmpPatchIndex; int rowBegin = 0; int colBegin = 0; m_patchIndex->clear(); for(int i = 0;i != rPatchNum; i++) { for(int j = 0;j != cPatchNum; j++) { if(0x00 == i && 0x00 == j) tmpPatchIndex.iPatch = 11; else if(0x00 == i && cPatchNum-1 == j) tmpPatchIndex.iPatch = 12; else if(rPatchNum-1 == i && cPatchNum-1 == j) tmpPatchIndex.iPatch = 13; else if(rPatchNum-1 == i && 0x00 == j) tmpPatchIndex.iPatch = 14; else if(0x00 == i && j>0 && j< cPatchNum-1) tmpPatchIndex.iPatch = 21; else if(j == cPatchNum -1 && i>0 && i<rPatchNum -1) tmpPatchIndex.iPatch = 22; else if(i == rPatchNum-1 && j>0 && j<cPatchNum -1) tmpPatchIndex.iPatch = 23; else if(0x00 == j && i > 0 && i<rPatchNum -1) tmpPatchIndex.iPatch = 24; else tmpPatchIndex.iPatch = 31; tmpPatchIndex.row_begin = rowBegin; tmpPatchIndex.col_begin = colBegin; if(rowBegin+m_patchSize.height > m_imgHeigth) tmpPatchIndex.heigth = m_imgHeigth - rowBegin; else tmpPatchIndex.heigth = m_patchSize.height; if(colBegin+m_patchSize.width > m_imgWidth) tmpPatchIndex.width = m_imgWidth - colBegin; else tmpPatchIndex.width = m_patchSize.width; m_patchIndex->push_back(tmpPatchIndex); colBegin = colBegin + m_patchSize.width - m_overlappedPixel; } rowBegin = rowBegin + m_patchSize.height - m_overlappedPixel; colBegin = 0; } return (int)m_patchIndex->size(); } void GDALOpenCV::GetROIFromPatchIndex(const int index,cv::Mat &img) { int patchNum = (int)m_patchIndex->size(); if(index > patchNum || index < 1) return; PatchIndex curPatchIndex = m_patchIndex->at(index-1); int patchRowBegin = curPatchIndex.row_begin; int patchColBegin = curPatchIndex.col_begin; int patchWidth = curPatchIndex.width; int patchHeight = curPatchIndex.heigth; std::vector<cv::Mat> *imgMat = new std::vector<cv::Mat>(m_bandNum);// 存储读取的每个波段数据 void *pafBuffer = AllocateMemory(m_dataType,patchWidth*patchHeight); // 内存分配 GDALRasterBand *pBand = NULL; cv::Mat *tmpMat = NULL; int iBand = 0; // 波段标记 while(iBand<m_bandNum) { pBand = m_poDataSet->GetRasterBand(++iBand); pBand->RasterIO(GF_Read,patchColBegin,patchRowBegin,patchWidth,patchHeight,pafBuffer, patchWidth,patchHeight,GCType2GDALType(m_dataType),0,0); tmpMat =new cv::Mat(patchHeight,patchWidth,GCType2OPenCVType(m_dataType),pafBuffer); imgMat->at(iBand-1) = (*tmpMat).clone(); delete tmpMat; tmpMat = NULL; } cv::merge(*imgMat,img); delete pafBuffer;pafBuffer = NULL; //delete pBand;pBand = NULL; imgMat->clear();delete imgMat;imgMat = NULL; } bool GDALOpenCV::SetROIMatToFileByIndex( const std::string outFileName,cv::Mat &img, const int index,const int flag /*= 1*/ ) { if(!outFileName.c_str() || img.empty()) return false; const int nBandCount=img.channels(); const int nImgSizeX=img.cols; const int nImgSizeY=img.rows; PatchIndex tmpPatchIndex = m_patchIndex->at(index-1); if(tmpPatchIndex.heigth != nImgSizeY || tmpPatchIndex.width != nImgSizeX) return false; std::vector<cv::Mat> *imgMat = new std::vector<cv::Mat>(m_bandNum); cv::split(img,*imgMat); const int ty = (*imgMat).at(0).type(); GDALAllRegister(); //GDALDataset *poDataset = NULL; //GDAL数据集 GDALDriver *poDriver = NULL; //驱动,用于创建新的文件 //////////////////////////////// ///flag:1 ====》TIFF /// 2 ====》HFA /// 3 ====》ENVI std::string pszFormat; //存储数据类型 switch (flag) { case 1: pszFormat = "GTiff"; break; case 2: pszFormat = "HFA"; break; case 3: pszFormat = "ENVI"; break; default: return 0; } poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat.c_str()); int OPenCVty = imgMat->at(0).type(); GCDataType GCty = OPenCVType2GCType(OPenCVty); if(poDriver == NULL) return 0; if(m_outPoDataSet == NULL) { m_outPoDataSet=poDriver->Create(outFileName.c_str(),m_imgWidth,m_imgHeigth,nBandCount, GCType2GDALType(GCty),NULL); m_outPoDataSet->SetProjection(m_poDataSet->GetProjectionRef()); double dGeotransform[6]; m_poDataSet->GetGeoTransform(dGeotransform); m_outPoDataSet->SetGeoTransform(dGeotransform); } // 循环写入文件 GDALRasterBand *pBand = NULL; int n1 = nImgSizeY; int nc = nImgSizeX; int overPix = int(m_overlappedPixel/2); void *ppafScan = NULL; int curCol = 0; int curRow = 0; for(int i = 1;i<=nBandCount;i++) { pBand = m_outPoDataSet->GetRasterBand(i); cv::Mat tmpMat; tmpMat = imgMat->at(i-1); // 文件的写入 if(tmpPatchIndex.iPatch == 11) { curCol = nImgSizeX-overPix; curRow = nImgSizeY - overPix; cv::Rect r1(0,0,curCol,curRow); tmpMat = tmpMat(r1); cv::Mat *newMat = new cv::Mat(curRow,curCol,ty); *newMat = tmpMat.clone(); ppafScan = AllocateMemory(GCty,curCol*curRow); if((*newMat).isContinuous()) SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow); else return false; pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin,tmpPatchIndex.row_begin, curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0); delete newMat;newMat = NULL; } if(tmpPatchIndex.iPatch == 12) { curCol = nImgSizeX-overPix; curRow = nImgSizeY - overPix; cv::Rect r1(overPix,0,curCol,curRow); tmpMat = tmpMat(r1); cv::Mat *newMat = new cv::Mat(curRow,curCol,ty); *newMat = tmpMat.clone(); ppafScan = AllocateMemory(GCty,curCol*curRow); if((*newMat).isContinuous()) SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow); else return false; pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin+overPix,tmpPatchIndex.row_begin, curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0); delete newMat;newMat = NULL; } if(tmpPatchIndex.iPatch == 13) { curCol = nImgSizeX-overPix; curRow = nImgSizeY - overPix; cv::Rect r1(overPix,overPix,curCol,curRow); tmpMat = tmpMat(r1); cv::Mat *newMat = new cv::Mat(curRow,curCol,ty); *newMat = tmpMat.clone(); ppafScan = AllocateMemory(GCty,curCol*curRow); if((*newMat).isContinuous()) SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow); else return false; pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin+overPix,tmpPatchIndex.row_begin+overPix, curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0); delete newMat;newMat = NULL; } if(tmpPatchIndex.iPatch == 14) { curCol = nImgSizeX-overPix; curRow = nImgSizeY - overPix; cv::Rect r1(0,overPix,curCol,curRow); tmpMat = tmpMat(r1); cv::Mat *newMat = new cv::Mat(curRow,curCol,ty); *newMat = tmpMat.clone(); ppafScan = AllocateMemory(GCty,curCol*curRow); if((*newMat).isContinuous()) SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow); else return false; pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin,tmpPatchIndex.row_begin+overPix, curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0); delete newMat;newMat = NULL; } if(tmpPatchIndex.iPatch == 21) { curCol = nImgSizeX-2*overPix; curRow = nImgSizeY - overPix; cv::Rect r1(overPix,0,curCol,curRow); tmpMat = tmpMat(r1); cv::Mat *newMat = new cv::Mat(curRow,curCol,ty); *newMat = tmpMat.clone(); ppafScan = AllocateMemory(GCty,curCol*curRow); if((*newMat).isContinuous()) SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow); else return false; pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin+overPix,tmpPatchIndex.row_begin, curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0); delete newMat;newMat = NULL; } if(tmpPatchIndex.iPatch == 22) { curCol = nImgSizeX- overPix; curRow = nImgSizeY - 2*overPix; cv::Rect r1(overPix,overPix,curCol,curRow); tmpMat = tmpMat(r1); cv::Mat *newMat = new cv::Mat(curRow,curCol,ty); *newMat = tmpMat.clone(); ppafScan = AllocateMemory(GCty,curCol*curRow); if((*newMat).isContinuous()) SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow); else return false; pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin+overPix,tmpPatchIndex.row_begin+overPix, curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0); delete newMat;newMat = NULL; } if(tmpPatchIndex.iPatch == 23) { curCol = nImgSizeX- 2*overPix; curRow = nImgSizeY - overPix; cv::Rect r1(overPix,overPix,curCol,curRow); tmpMat = tmpMat(r1); cv::Mat *newMat = new cv::Mat(curRow,curCol,ty); *newMat = tmpMat.clone(); ppafScan = AllocateMemory(GCty,curCol*curRow); if((*newMat).isContinuous()) SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow); else return false; pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin+overPix,tmpPatchIndex.row_begin+overPix, curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0); delete newMat;newMat = NULL; } if(tmpPatchIndex.iPatch == 24) { curCol = nImgSizeX- overPix; curRow = nImgSizeY - 2*overPix; cv::Rect r1(0,overPix,curCol,curRow); tmpMat = tmpMat(r1); cv::Mat *newMat = new cv::Mat(curRow,curCol,ty); *newMat = tmpMat.clone(); ppafScan = AllocateMemory(GCty,curCol*curRow); if((*newMat).isContinuous()) SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow); else return false; pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin,tmpPatchIndex.row_begin+overPix, curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0); delete newMat;newMat = NULL; } if(tmpPatchIndex.iPatch == 31) { curCol = nImgSizeX- 2*overPix; curRow = nImgSizeY - 2*overPix; cv::Rect r1(overPix,overPix,curCol,curRow); tmpMat = tmpMat(r1); cv::Mat *newMat = new cv::Mat(curRow,curCol,ty); *newMat = tmpMat.clone(); ppafScan = AllocateMemory(GCty,curCol*curRow); if((*newMat).isContinuous()) SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow); else return false; pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin+overPix,tmpPatchIndex.row_begin+overPix, curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0); delete newMat;newMat = NULL; } } delete ppafScan;ppafScan = NULL; imgMat->clear();delete imgMat;imgMat = NULL; return 1; } GCDataType GDALOpenCV::GDALType2GCType( const GDALDataType ty ) { switch(ty) { case GDT_Byte: return GC_Byte; case GDT_UInt16: return GC_UInt16; case GDT_Int16: return GC_Int16; case GDT_UInt32: return GC_UInt32; case GDT_Int32: return GC_Int32; case GDT_Float32: return GC_Float32; case GDT_Float64: return GC_Float64; default: assert(false); return GC_ERRType; } } GCDataType GDALOpenCV::OPenCVType2GCType( const int ty ) { switch(ty) { case 0: return GC_Byte; case 2: return GC_UInt16; case 3: return GC_Int16; case 4: return GC_Int32; case 5: return GC_Float32; case 6: return GC_Float64; default: assert(false); return GC_ERRType; } } GDALDataType GDALOpenCV::GCType2GDALType( const GCDataType ty ) { switch(ty) { case GC_Byte: return GDT_Byte; case GC_UInt16: return GDT_UInt16; case GC_Int16: return GDT_Int16; case GC_UInt32: return GDT_UInt32; case GC_Int32: return GDT_Int32; case GC_Float32: return GDT_Float32; case GC_Float64: return GDT_Float64; default: assert(false); return GDT_TypeCount; } } int GDALOpenCV::GCType2OPenCVType( const GCDataType ty ) { switch(ty) { case GC_Byte: return 0; case GC_UInt16: return 2; case GC_Int16: return 3; case GC_Int32: return 4; case GC_Float32: return 5; case GC_Float64: return 6; default: assert(false); return -1; } } void* GDALOpenCV::AllocateMemory(const GCDataType lDataType,const long long lSize ) { assert(0!=lSize); void* pvData = NULL; switch (lDataType) { case GC_Byte: pvData = new(std::nothrow) unsigned char[lSize]; break; case GC_UInt16: pvData = new(std::nothrow) unsigned short int[lSize]; break; case GC_Int16: pvData = new(std::nothrow) short int[lSize]; break; case GC_UInt32: pvData = new(std::nothrow) unsigned long[lSize]; break; case GC_Int32: pvData = new(std::nothrow) long[lSize]; break; case GC_Float32: pvData = new(std::nothrow) float[lSize]; break; case GC_Float64: pvData = new(std::nothrow) double[lSize]; break; default: assert(false); break; } return pvData; } void* GDALOpenCV::SetMemCopy( void *dst,const void *src, const GCDataType lDataType, const long long lSize ) { assert(0!=lSize); switch (lDataType) { case GC_Byte: return memmove(dst,src,sizeof(unsigned char)*lSize); case GC_UInt16: return memmove(dst,src,sizeof(unsigned short)*lSize); case GC_Int16: return memmove(dst,src,sizeof(short int)*lSize); case GC_UInt32: return memmove(dst,src,sizeof(unsigned long)*lSize); case GC_Int32: return memmove(dst,src,sizeof(long)*lSize); case GC_Float32: return memmove(dst,src,sizeof(float)*lSize); case GC_Float64: return memmove(dst,src,sizeof(double)*lSize); default: return NULL; } }
这个类我已经用了一段时间,可以直接使用,如果有啥bug,还请与我交流,共同提高。
放松不放纵--忙碌不盲目