• 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

  • 相关阅读:
    第07组 Beta冲刺(3/5)
    第07组 Beta冲刺(2/5)
    第07组 Beta冲刺(1/5)
    第07组 Alpha事后诸葛亮
    第07组 Alpha冲刺(6/6)
    第07组 Alpha冲刺(5/6)
    【置顶】CSP/NOIP 2020 (高二游记)
    【置顶】CSP/S 2019退役祭
    【置顶】一些关于停课的感想(随时更新,连着前一篇博客)11/11~11/15
    【置顶】我的2018~2019信息学之路
  • 原文地址:https://www.cnblogs.com/bigbigtree/p/2267021.html
Copyright © 2020-2023  润新知