VC+AO中读取ArcGIS支持栅格像素值(转载)
在VC+AO中想要读取img,grid,tif,tiff,bmp,jpg等ArcGIS支持的栅格像素值,先用下面这个类成员函数获取IPixelBlock接口对象的值,同时得到栅格图像的属性保存在IRasterProps接口对象中,然后再定义SAFEARRAY变量从中获取像素值,这是个难点。
//读取ArcGIS支持的栅格数据,得到IPixelBlock,返回数据类型,然后根据此类型定义不同类型数组接收数据,并得到栅格数据
rstPixelType CWzjAoRasterOp::ReadRaster(CString szPath, CString szFile, IPixelBlockPtr& ipBlock, IRasterPropsPtr& ipRasProps)
{
IWorkspacePtr ipWS;
IWorkspaceFactoryPtr ipWSF(CLSID_RasterWorkspaceFactory);
//If Not pWSF.IsWorkspace(sPath) Then Exit Sub
rstPixelType CWzjAoRasterOp::ReadRaster(CString szPath, CString szFile, IPixelBlockPtr& ipBlock, IRasterPropsPtr& ipRasProps)
{
IWorkspacePtr ipWS;
IWorkspaceFactoryPtr ipWSF(CLSID_RasterWorkspaceFactory);
//If Not pWSF.IsWorkspace(sPath) Then Exit Sub
ipWSF->OpenFromFile(CComBSTR(szPath), 0, &ipWS);
IRasterWorkspace2Ptr ipRWS(ipWS);
IRasterDatasetPtr ipRasterDS;
ipRWS->OpenRasterDataset(CComBSTR(szFile), &ipRasterDS);
IRasterPtr ipRaster;
ipRasterDS->CreateDefaultRaster(&ipRaster);
ipRasProps = ipRaster;
// Get RasterBand from the raster
IRasterBandPtr ipBand;
IRasterBandCollectionPtr ipBandCol(ipRaster);
ipBandCol->Item(0, &ipBand);
// QI RawPixel interface
IRawPixelsPtr ipRawPixel(ipBand);
// Create a DblPnt to hold the PixelBlock size
IPntPtr ipSize(CLSID_DblPnt);
long lWidth, lHeight;
ipRasProps->get_Width(&lWidth);
ipRasProps->get_Height(&lHeight);
ipSize->SetCoords(lWidth, lHeight);
// Create PixelBlock with defined size
ipRawPixel->CreatePixelBlock(ipSize, &ipBlock);
IPntPtr ipPnt(CLSID_DblPnt);
ipPnt->SetCoords(0,0);
ipRawPixel->Read(ipPnt, ipBlock);
rstPixelType rstTy;
ipBlock->get_PixelType(0, &rstTy);
return rstTy;
}
IRasterWorkspace2Ptr ipRWS(ipWS);
IRasterDatasetPtr ipRasterDS;
ipRWS->OpenRasterDataset(CComBSTR(szFile), &ipRasterDS);
IRasterPtr ipRaster;
ipRasterDS->CreateDefaultRaster(&ipRaster);
ipRasProps = ipRaster;
// Get RasterBand from the raster
IRasterBandPtr ipBand;
IRasterBandCollectionPtr ipBandCol(ipRaster);
ipBandCol->Item(0, &ipBand);
// QI RawPixel interface
IRawPixelsPtr ipRawPixel(ipBand);
// Create a DblPnt to hold the PixelBlock size
IPntPtr ipSize(CLSID_DblPnt);
long lWidth, lHeight;
ipRasProps->get_Width(&lWidth);
ipRasProps->get_Height(&lHeight);
ipSize->SetCoords(lWidth, lHeight);
// Create PixelBlock with defined size
ipRawPixel->CreatePixelBlock(ipSize, &ipBlock);
IPntPtr ipPnt(CLSID_DblPnt);
ipPnt->SetCoords(0,0);
ipRawPixel->Read(ipPnt, ipBlock);
rstPixelType rstTy;
ipBlock->get_PixelType(0, &rstTy);
return rstTy;
}
下面是从IPixelBlock接口对象中获取像素值的方法
LPBYTE pData = NULL;
//szPath 路径 szFileName 文件名
rstOp.ReadRaster(szPath, szFileName, ipBlock, ipRasProps);
VARIANT vVal;
ipBlock->get_SafeArray(0, &vVal);
SAFEARRAY* pSa = vVal.parray;
//pData中就保存像素值,只不过,是一维,得到的行列数后就可以看作二维数据了
SafeArrayAccessData(pSa, (void**)&pData);
//图像的行,列数
long lW, lH;
ipRasProps->get_Width(&lW);
ipRasProps->get_Height(&lH);
//szPath 路径 szFileName 文件名
rstOp.ReadRaster(szPath, szFileName, ipBlock, ipRasProps);
VARIANT vVal;
ipBlock->get_SafeArray(0, &vVal);
SAFEARRAY* pSa = vVal.parray;
//pData中就保存像素值,只不过,是一维,得到的行列数后就可以看作二维数据了
SafeArrayAccessData(pSa, (void**)&pData);
//图像的行,列数
long lW, lH;
ipRasProps->get_Width(&lW);
ipRasProps->get_Height(&lH);