GDAL VC6.0 (2)
GDAL是一个操作各种栅格和矢量地理数据格式的开源库。包括读取、写入、转换、处理各种栅格和矢量数据格式。它支持各种图像格式,其详细清单见: http://www.gdal.org/formats_list.htm 。
完成了图像的读取和显示,但不知这种方法是否为最佳,请各位指正,谢谢!
本文就以VC为开发平台介绍GDAL对图像数据的操作方法。
1.首先进行GDAl的配置工作,这在上文中已经提到,不再做陈述。
2.然后,我是在Doc类里面添加OnOpenDocument(LPCTSTR lpszPathName)函数,其具体的操作在其中进行。创建文件对话框:,返回lpszPathName.
- CFile file;
- CFileException fe;
- if (!file.Open(lpszPathName,CFile::modeRead | CFile::shareDenyWrite,&fe))
- {
- ReportSaveLoadException(lpszPathName,&fe,FALSE,AFX_IDP_FAILED_TO_CREATE_DOC);
- return FALSE;
- }
3.函数中,首先的进行驱动的注册。所使用的函数是GDALAllRegister()函数,然后进行打开文件操作,这里介绍一个DataSet概念,在GDAL中可以说数据的核心就是Dataset,简单来说可以将Dataset就理解为图像文件。在数据集下最重要组成部分就是所谓的波段band,文件的打开使用的是:GDALOpen函数。
- GDALDataset * DataSet; // 在这里数据集即为理解为图像文件
- GDALAllRegister(); //注册驱动,这项万不可少,必要步骤。
- DataSet = (GDALDataset *)GDALOpen(lpszPathName,GA_ReadOnly);//文件的打开使用的是GDALOpen函数
4.在确认DataSet不是NULL的情况下就可以对图像数据集进行操作了。
- if (DataSet == NULL)
- {
- AfxMessageBox("无法打开遥感图像");
- return 0;
- }
5.接下来,我们就开始进入到波段处理。波段的获取使用GetRasterBand函数,
- GDALRasterBand **pBand; //数据集下最重要的成分波段。
- int m_Bands = DataSet->GetRasterCount();
- pBand = new GDALRasterBand * [m_Bands]; //新建波段
- if (pBand == NULL)
- {
- AfxMessageBox("创建数据集波段失败");
- return 0;
- }
- for (int i =0;i<m_Bands;i++)
- {
- pBand[i] = DataSet->GetRasterBand(i+1);//预读取遥感的第一个波段,因该是这个作用吧!
- if (pBand[i] == NULL)
- {
- AfxMessageBox("创建i波段数据集失败!");
- return 0;
- }
- }
6,创建一个对话框,其布局如图所示:
对话框的设计此处就不作详述啦,它的作用是返回显示模式以及波段选择。
- CDlgBands dlg;
- dlg.m_mBands = m_Bands;
- if (dlg.m_mBands == 1)
- {
- dlg.mBandsType = 0;
- }
- else
- {
- dlg.mBandsType = 1;
- }
- 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.更新和释放指针
- UpdateAllViews(NULL);
- delete DataSet; //释放资源
- return TRUE;
要显示图像,当然得在View类的OnDraw()函数中添加必要的代码:
1.假如要打开的是灰度图像,先对数据头文件操作,包括数据头和颜色表的赋值。然后建立数据区,为各像素赋值,即完成图像的显示:
- if (pDoc->BandsType == 0)//GDI绘图法
- {
- //数据头文件
- //1.图像数据块头
- int i,j;
- int nWidth = pDoc->nXsize;
- int nHeight = pDoc->nYsize;
- BITMAPINFO * pBmpInfo = (BITMAPINFO*) new char[sizeof(BITMAPINFO) + sizeof(RGBQUAD)*(256)];
- pBmpInfo->bmiHeader.biBitCount = 8;
- pBmpInfo->bmiHeader.biClrImportant = 0;
- pBmpInfo->bmiHeader.biClrUsed = 0;
- pBmpInfo->bmiHeader.biCompression = BI_RGB;
- pBmpInfo->bmiHeader.biWidth = nWidth;
- pBmpInfo->bmiHeader.biHeight = nHeight;
- pBmpInfo->bmiHeader.biPlanes = 1;
- pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- pBmpInfo->bmiHeader.biSizeImage = (nWidth*8+31)/32*4*nHeight;
- pBmpInfo->bmiHeader.biXPelsPerMeter = 0;
- pBmpInfo->bmiHeader.biYPelsPerMeter = 0;
- //2.颜色表
- for (i = 0;i < 256;i++)
- {
- pBmpInfo->bmiColors[i].rgbRed = i;
- pBmpInfo->bmiColors[i].rgbGreen = i;
- pBmpInfo->bmiColors[i].rgbBlue = i;
- pBmpInfo->bmiColors[i].rgbReserved = 0;
- }
- //建立数据区
- LONG LineBytes = (nWidth*8+31)/32*4;
- LPBYTE pData = (LPBYTE)new char[LineBytes*nHeight];
- //为各像素赋值!!!!!!
- for (i=0;i<nHeight;i++)
- {
- for (j=0;j<nWidth;j++)
- {
- pData[(nHeight-i-1)*LineBytes + j] = pDoc->poBandBlock_Gray[i*nWidth+j];//此表达式有待研究
- }
- }
- SetStretchBltMode(pDC->m_hDC,BLACKONWHITE|WHITEONBLACK);
- StretchDIBits(pDC->m_hDC, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
- pData, pBmpInfo, DIB_RGB_COLORS, SRCCOPY);
- UpdateWindow();
- delete pBmpInfo;
- delete pData;
- }
2,当然打开彩色图像也要如此操作
- if (pDoc->BandsType == 1)//GDI绘图法
- {
- //数据头文件
- //1.图像数据块头
- int i,j,k;
- int nWidth = pDoc->nXsize;
- int nHeight = pDoc->nYsize;
- BITMAPINFO * pBmpInfo = (BITMAPINFO*) new char[sizeof(BITMAPINFO) + sizeof(RGBQUAD)*(256)];
- pBmpInfo->bmiHeader.biBitCount = 24;
- pBmpInfo->bmiHeader.biClrImportant = 0;
- pBmpInfo->bmiHeader.biClrUsed = 0;
- pBmpInfo->bmiHeader.biCompression = BI_RGB;
- pBmpInfo->bmiHeader.biWidth = nWidth;
- pBmpInfo->bmiHeader.biHeight = nHeight;
- pBmpInfo->bmiHeader.biPlanes = 1;
- pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- pBmpInfo->bmiHeader.biSizeImage = (nWidth*24+31)/32*4*nHeight;
- pBmpInfo->bmiHeader.biXPelsPerMeter = 0;
- pBmpInfo->bmiHeader.biYPelsPerMeter = 0;
- //2.颜色表
- for (i = 0;i < 256;i++)
- {
- pBmpInfo->bmiColors[i].rgbRed = i;
- pBmpInfo->bmiColors[i].rgbGreen = i;
- pBmpInfo->bmiColors[i].rgbBlue = i;
- pBmpInfo->bmiColors[i].rgbReserved = 0;
- }
- //建立数据区
- LONG LineBytes = (nWidth*24+31)/32*4;
- LPBYTE pData = (LPBYTE)new char[LineBytes*nHeight*3];
- //为各像素赋值!!!!!!
- for (i=0;i<nHeight;i++)
- {
- for (j=0,k=0;j<nWidth,k<3*nWidth;j++,k+=3)
- {
- // pData[(nHeight-i-1)*LineBytes + j] = pDoc->poBandBlock_Gray[i*nWidth+j];//此表达式有待研究
- pData[(nHeight-i-1)*LineBytes + k] = pDoc->poBandBlock_B[i*nWidth + j];
- pData[(nHeight-i-1)*LineBytes + k+1] = pDoc->poBandBlock_G[i*nWidth + j];
- pData[(nHeight-i-1)*LineBytes + k+2] = pDoc->poBandBlock_R[i*nWidth + j];
- }
- }
- SetStretchBltMode(pDC->m_hDC,BLACKONWHITE|WHITEONBLACK);
- StretchDIBits(pDC->m_hDC, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
- pData, pBmpInfo, DIB_RGB_COLORS, SRCCOPY);
- UpdateWindow();
- delete pBmpInfo;
- delete pData;
- }