天天看点

VC GDAl 读取并显示图像

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,创建一个对话框,其布局如图所示:

VC GDAl 读取并显示图像

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

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;

}