GDAL VC6.0 (2)

GDAL是一个操作各种栅格和矢量地理数据格式的开源库。包括读取、写入、转换、处理各种栅格和矢量数据格式。它支持各种图像格式,其详细清单见: http://www.gdal.org/formats_list.htm  。

 完成了图像的读取和显示,但不知这种方法是否为最佳,请各位指正,谢谢!

本文就以VC为开发平台介绍GDAL对图像数据的操作方法。

1.首先进行GDAl的配置工作,这在上文中已经提到,不再做陈述。

2.然后,我是在Doc类里面添加OnOpenDocument(LPCTSTR lpszPathName)函数,其具体的操作在其中进行。创建文件对话框:,返回lpszPathName.

 
  1. CFile file;  
  2.     CFileException fe;  
  3.     if (!file.Open(lpszPathName,CFile::modeRead | CFile::shareDenyWrite,&fe))  
  4.     {  
  5.         ReportSaveLoadException(lpszPathName,&fe,FALSE,AFX_IDP_FAILED_TO_CREATE_DOC);  
  6.         return FALSE;  
  7.   }  

 

3.函数中,首先的进行驱动的注册。所使用的函数是GDALAllRegister()函数,然后进行打开文件操作,这里介绍一个DataSet概念,GDAL中可以说数据的核心就是Dataset,简单来说可以将Dataset就理解为图像文件。在数据集下最重要组成部分就是所谓的波段band,文件的打开使用的是:GDALOpen函数。

 
  1. GDALDataset * DataSet;          // 在这里数据集即为理解为图像文件   
  2.     GDALAllRegister();              //注册驱动,这项万不可少,必要步骤。   
  3.  DataSet = (GDALDataset *)GDALOpen(lpszPathName,GA_ReadOnly);//文件的打开使用的是GDALOpen函数  

4.在确认DataSet不是NULL的情况下就可以对图像数据集进行操作了。

 

 

 
 
  1. if (DataSet == NULL)  
  2.     {  
  3.         AfxMessageBox("无法打开遥感图像");  
  4.     return 0;  
  5.   }  

 5.接下来,我们就开始进入到波段处理。波段的获取使用GetRasterBand函数,

 
 
  1. GDALRasterBand **pBand;        //数据集下最重要的成分波段。   
  2.     int m_Bands = DataSet->GetRasterCount();  
  3. pBand = new GDALRasterBand * [m_Bands]; //新建波段   
  4.  if (pBand == NULL)  
  5.  {  
  6.   AfxMessageBox("创建数据集波段失败");  
  7.   return 0;  
  8.   }  
  9.     for (int i =0;i<m_Bands;i++)  
  10.     {  
  11.        pBand[i] = DataSet->GetRasterBand(i+1);//预读取遥感的第一个波段,因该是这个作用吧!   
  12.         if (pBand[i] == NULL)  
  13.        {  
  14.            AfxMessageBox("创建i波段数据集失败!");  
  15.            return 0;  
  16.        }  
  17.     }  

6,创建一个对话框,其布局如图所示:

对话框的设计此处就不作详述啦,它的作用是返回显示模式以及波段选择。

 
 
  1. CDlgBands dlg;  
  2. dlg.m_mBands = m_Bands;  
  3. if (dlg.m_mBands == 1)  
  4. {  
  5.     dlg.mBandsType = 0;  
  6. }  
  7. else  
  8. {  
  9.     dlg.mBandsType = 1;  
  10. }  
  11. dlg.DoModal();  

7,进入我认为最重要的步骤:波段数据的读写核心函数就是RasterIO。这个函数可以将图像的某一个子块读入或写入。当然此处要判断一下要打开的的是灰度图像还是彩色图像。

 
 

 

             if (dlg.mBandsType == 0)//打开灰色图像   

             {  

              BandsType = dlg.mBandsType;  

              BdCGray = dlg.BdChoiceGray;  

              if (pBand[BdCGray] == NULL)  

  •     {  
  •         return 0;  
  •     }  
  •     nXsize = pBand[BdCGray]->GetXSize();  
  •     nYsize = pBand[BdCGray]->GetYSize();                              //数据块的xy方向像素尺寸   
  •     poBandBlock_Gray = (BYTE*)CPLMalloc(sizeof(BYTE)*(nXsize*nYsize));//分配缓冲区空间   
  •     //RasterIO函数可以将图像的某一个子块读入或写入   
  •     pBand[BdCGray]->RasterIO(GF_Read, 0, 0, nXsize,  
  •                 nYsize, poBandBlock_Gray, nXsize, nYsize, pBand[BdCGray]->GetRasterDataType(), 0, 0);  
  • }  
  • if (dlg.mBandsType == 1)  
  • {  
  •     BandsType = dlg.mBandsType;  
  •     BdCR = dlg.BdChoiceR;  
  •     BdCG = dlg.BdChoiceG;  
  •     BdCB = dlg.BdChoiceB;  
  •       
  •     int nXsizeR,nXsizeG,nXsizeB;  
  •     int nYsizeR,nYsizeG,nYsizeB;  
  •   
  •     nXsizeR = pBand[BdCR]->GetXSize();  
  •     nYsizeR = pBand[BdCR]->GetYSize();  
  •     nXsizeG = pBand[BdCG]->GetXSize();  
  •     nYsizeG = pBand[BdCG]->GetYSize();  
  •     nXsizeB = pBand[BdCB]->GetXSize();  
  •     nYsizeB = pBand[BdCB]->GetYSize();  
  •   
  •     nXsize = nXsizeR;  
  •     nYsize = nYsizeR;  
  •   
  •     poBandBlock_R = (BYTE*)CPLMalloc(sizeof(BYTE)*(nXsizeR*nYsizeR));  
  •     poBandBlock_G = (BYTE*)CPLMalloc(sizeof(BYTE)*(nXsizeG*nYsizeG));  
  •     poBandBlock_B = (BYTE*)CPLMalloc(sizeof(BYTE)*(nXsizeB*nYsizeB));  
  •   
  •     pBand[BdCR]->RasterIO(GF_Read,0,0,nXsizeR,nYsizeR,poBandBlock_R,nXsizeR,nYsizeR,pBand[BdCR]->GetRasterDataType(),0,0);  
  •     pBand[BdCG]->RasterIO(GF_Read,0,0,nXsizeG,nYsizeG,poBandBlock_G,nXsizeG,nYsizeG,pBand[BdCG]->GetRasterDataType(),0,0);  
  •     pBand[BdCB]->RasterIO(GF_Read,0,0,nXsizeB,nYsizeB,poBandBlock_B,nXsizeB,nYsizeB,pBand[BdCB]->GetRasterDataType(),0,0);  
  •   
  • }  

 8.更新和释放指针

 
 
  1. UpdateAllViews(NULL);  
  2.     delete DataSet; //释放资源     
  3.     return TRUE;  

要显示图像,当然得在View类的OnDraw()函数中添加必要的代码:

1.假如要打开的是灰度图像,先对数据头文件操作,包括数据头和颜色表的赋值。然后建立数据区,为各像素赋值,即完成图像的显示:

 
 
  1. if (pDoc->BandsType == 0)//GDI绘图法   
  2.     {  
  3.         //数据头文件   
  4.         //1.图像数据块头   
  5.         int i,j;  
  6.         int  nWidth = pDoc->nXsize;  
  7.         int nHeight = pDoc->nYsize;  
  8.         BITMAPINFO * pBmpInfo = (BITMAPINFO*) new char[sizeof(BITMAPINFO) + sizeof(RGBQUAD)*(256)];  
  9.         pBmpInfo->bmiHeader.biBitCount = 8;  
  10.         pBmpInfo->bmiHeader.biClrImportant = 0;  
  11.         pBmpInfo->bmiHeader.biClrUsed = 0;  
  12.         pBmpInfo->bmiHeader.biCompression = BI_RGB;  
  13.         pBmpInfo->bmiHeader.biWidth = nWidth;  
  14.         pBmpInfo->bmiHeader.biHeight = nHeight;  
  15.         pBmpInfo->bmiHeader.biPlanes = 1;  
  16.         pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);  
  17.         pBmpInfo->bmiHeader.biSizeImage = (nWidth*8+31)/32*4*nHeight;  
  18.         pBmpInfo->bmiHeader.biXPelsPerMeter = 0;  
  19.         pBmpInfo->bmiHeader.biYPelsPerMeter = 0;  
  20.         //2.颜色表   
  21.         for (i = 0;i < 256;i++)  
  22.         {  
  23.             pBmpInfo->bmiColors[i].rgbRed   = i;  
  24.             pBmpInfo->bmiColors[i].rgbGreen = i;  
  25.             pBmpInfo->bmiColors[i].rgbBlue  = i;  
  26.             pBmpInfo->bmiColors[i].rgbReserved = 0;  
  27.         }  
  28.   
  29.   
  30.         //建立数据区   
  31.         LONG LineBytes = (nWidth*8+31)/32*4;  
  32.         LPBYTE pData = (LPBYTE)new char[LineBytes*nHeight];  
  33.         //为各像素赋值!!!!!!   
  34.         for (i=0;i<nHeight;i++)  
  35.         {  
  36.             for (j=0;j<nWidth;j++)  
  37.             {  
  38.                 pData[(nHeight-i-1)*LineBytes + j] = pDoc->poBandBlock_Gray[i*nWidth+j];//此表达式有待研究   
  39.             }  
  40.         }  
  41.   
  42.         SetStretchBltMode(pDC->m_hDC,BLACKONWHITE|WHITEONBLACK);  
  43.         StretchDIBits(pDC->m_hDC, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,   
  44.             pData, pBmpInfo, DIB_RGB_COLORS, SRCCOPY);  
  45.           
  46.         UpdateWindow();  
  47.         delete pBmpInfo;  
  48.         delete pData;  
  49.   
  50.     }  

2,当然打开彩色图像也要如此操作

 

 
 
  1. if (pDoc->BandsType == 1)//GDI绘图法   
  2. {  
  3.     //数据头文件   
  4.     //1.图像数据块头   
  5.     int i,j,k;  
  6.     int  nWidth = pDoc->nXsize;  
  7.     int nHeight = pDoc->nYsize;  
  8.     BITMAPINFO * pBmpInfo = (BITMAPINFO*) new char[sizeof(BITMAPINFO) + sizeof(RGBQUAD)*(256)];  
  9.     pBmpInfo->bmiHeader.biBitCount = 24;  
  10.     pBmpInfo->bmiHeader.biClrImportant = 0;  
  11.     pBmpInfo->bmiHeader.biClrUsed = 0;  
  12.     pBmpInfo->bmiHeader.biCompression = BI_RGB;  
  13.     pBmpInfo->bmiHeader.biWidth = nWidth;  
  14.     pBmpInfo->bmiHeader.biHeight = nHeight;  
  15.     pBmpInfo->bmiHeader.biPlanes = 1;  
  16.     pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);  
  17.     pBmpInfo->bmiHeader.biSizeImage = (nWidth*24+31)/32*4*nHeight;  
  18.     pBmpInfo->bmiHeader.biXPelsPerMeter = 0;  
  19.     pBmpInfo->bmiHeader.biYPelsPerMeter = 0;  
  20.     //2.颜色表   
  21.     for (i = 0;i < 256;i++)  
  22.     {  
  23.         pBmpInfo->bmiColors[i].rgbRed   = i;  
  24.         pBmpInfo->bmiColors[i].rgbGreen = i;  
  25.         pBmpInfo->bmiColors[i].rgbBlue  = i;  
  26.         pBmpInfo->bmiColors[i].rgbReserved = 0;  
  27.     }  
  28.       
  29.       
  30.     //建立数据区   
  31.     LONG LineBytes = (nWidth*24+31)/32*4;  
  32.     LPBYTE pData = (LPBYTE)new char[LineBytes*nHeight*3];  
  33.     //为各像素赋值!!!!!!   
  34.     for (i=0;i<nHeight;i++)  
  35.     {  
  36.         for (j=0,k=0;j<nWidth,k<3*nWidth;j++,k+=3)  
  37.         {  
  38.         //  pData[(nHeight-i-1)*LineBytes + j] = pDoc->poBandBlock_Gray[i*nWidth+j];//此表达式有待研究   
  39.             pData[(nHeight-i-1)*LineBytes + k] = pDoc->poBandBlock_B[i*nWidth + j];  
  40.             pData[(nHeight-i-1)*LineBytes + k+1] = pDoc->poBandBlock_G[i*nWidth + j];  
  41.             pData[(nHeight-i-1)*LineBytes + k+2] = pDoc->poBandBlock_R[i*nWidth + j];  
  42.         }  
  43.     }  
  44.       
  45.     SetStretchBltMode(pDC->m_hDC,BLACKONWHITE|WHITEONBLACK);  
  46.     StretchDIBits(pDC->m_hDC, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,   
  47.         pData, pBmpInfo, DIB_RGB_COLORS, SRCCOPY);  
  48.       
  49.     UpdateWindow();  
  50.     delete pBmpInfo;  
  51.     delete pData;  
  52.       
  53. }  

转自:http://blog.csdn.net/hantaook/article/details/6368884

原文地址:https://www.cnblogs.com/bigbigtree/p/2267021.html