http://www.gissky.net- GIS空间站

我要投稿 投稿指南 RSS订阅 网站资讯通告:
搜索: 您现在的位置: GIS空间站 >> 技术专栏 >> ArcGIS >> ArcObjects开发 >> 正文

用灰度矩阵在AO中生成单波段栅格图像

作者:3S_Studi…    文章来源:本站原创    点击数:    更新时间:2007-9-25
摘要:在VC中定义矩阵,然后填充灰度矩阵,有了值后,就可以生成一幅栅格图像。同样可以读取已有的图像数据,修改之,或处理、计算等生成别的图像等。

开门见山,先把这个函数拿出来,看函数实现之前,我想先说一说各参数。
1,szPath是生成的栅格的路径
2,szFile是生成的栅格的文件名
3,rstInfo是RasterInfo结构体变量,是生成栅格的一些参数信息

struct RasterInfo { 
 IPointPtr ipOrigin; //栅格原点坐标
 long lColCount; //栅格列数
 long lRowCount; //栅格行数
 double dCellSizeX; //栅格X分辨率,X方向每像素大小
 double dCellSizeY; //栅格Y分辨率,Y方向每像素大小
 long lNumbands; //波段数
 ISpatialReferencePtr ipSpaRef; //空间参考
 rstPixelType rstTy; //数据类型,具体为:
Constant Value Description
PT_U1 0 Pixel values are 1 bit.
PT_U2 1 Pixel values are 2 bits.
PT_U4 2 Pixel values are 4 bits.
PT_UCHAR 3 Pixel values are unsigned 8 bit integers.
PT_CHAR 4 Pixel values are 8 bit integers.
PT_USHORT 5 Pixel values are unsigned 16 bit integers.
PT_SHORT 6 Pixel values are 16 bit integers.
PT_ULONG 7 Pixel values are unsigned 32 bit integers.
PT_LONG 8 Pixel values are 32 bit integers.
PT_FLOAT 9 Pixel values are single precision floating point.
PT_DOUBLE 10 Pixel values are double precision floating point.
PT_COMPLEX 11 Pixel values are complex.
PT_DCOMPLEX 12 Pixel values are double precision complex.  
//为了方便赋值,做了结构体的构造函数
RasterFormat(IPointPtr ipOrg, long lColC, long lRowC, double dCSX, double dCSY, long lNumBDS, rstPixelType ty, ISpatialReferencePtr ipSF)
 {
  ipOrigin = ipOrg;
  lColCount = lColC;
  lRowCount = lRowC;
  dCellSizeX = dCSX;
  dCellSizeY = dCSY;
  lNumbands = lNumBDS;
  rstTy = ty;
  ipSpaRef = ipSF;
 };
//为了能从栅格属性接口中得到栅格信息赋值,做了下面这个函数,目的还是方便给结构体赋值。
 FromRasProps(IRasterPropsPtr ipRasProps, double dCSX, double dCSY, long lNumBDS,rstPixelType ty= PT_UCHAR, ISpatialReferencePtr ipSF = NULL){
  IEnvelopePtr ipEnv;
  ipRasProps->get_Extent(&ipEnv);
  double x, y;
  ipEnv->get_XMin(&x);
  ipEnv->get_YMin(&y);
  IPointPtr ipPt(CLSID_Point);  
  ipPt->PutCoords(x,y);
  ipOrigin = ipPt;
  ipRasProps->get_Width(&lColCount);
  ipRasProps->get_Height(&lRowCount);
  dCellSizeX = dCSX;
  dCellSizeY = dCSY;
  lNumbands = lNumBDS;
  rstTy = ty;
  ipSpaRef = ipSF;
 };
};
4,pData是一个BYTE**(LPBYTE)类型的数组,
5,szRasFormat是栅格类型枚举,其定义为

enum RasterFormat
{
 IMAGINE_Image,
 TIFF,
 GRID
};
6,bNoDataValue是透明灰度值,不过现在我还没有研究明白,实现不了效果,哪们朋友研究清楚了,可以指点一下。
//下面才是真正的函数开始了。
//生成ArcGIS支持的栅格数据
void CWzjAoRasterOp::WriteRaster(CString szPath, CString szFile, RasterInfo rstInfo, LPBYTE pData, CString szRasFormat /*= "IMAGINE Image"*/, BYTE bNoDataValue /*= 256*/)     
{
 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;//szRasFormat),
 ipRWS->CreateRasterDataset(CComBSTR(szFile), CComBSTR(szRasFormat),  rstInfo.ipOrigin, rstInfo.lColCount,
  rstInfo.lRowCount, rstInfo.dCellSizeX, rstInfo.dCellSizeY, rstInfo.lNumbands, rstInfo.rstTy, rstInfo.ipSpaRef, TRUE, &ipRasterDS);
 
 IRasterPtr ipRaster;
 ipRasterDS->CreateDefaultRaster(&ipRaster); 
 IRasterPropsPtr ipRasProps =  ipRaster; 

 // Get RasterBand from the raster
 IRasterBandPtr ipBand;
 IRasterBandCollectionPtr ipBandCol(ipRaster);
 ipBandCol->Item(0, &ipBand);
 
 //目前这个设置透明色值不管用,不知道正确的方法是怎么样
 /*if (bNoDataValue > 0 || bNoDataValue < 256) {
  VARIANT vVal;
  vVal.vt = VT_UI1;
  vVal.cVal = bNoDataValue;
 // ipRasProps->put_NoDataValue(vVal);
  ipRasProps->put_NoDataValue(CComVariant(bNoDataValue));
 } 
 */// QI RawPixel interface
 IRawPixelsPtr ipRawPixel(ipBand);
 ipRasProps =  ipRaster; 

 // 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

 IPntPtr ipPnt(CLSID_DblPnt);  
 ipPnt->SetCoords(0,0); 
 
 IPixelBlockPtr ipBlock;
 ipRawPixel->CreatePixelBlock(ipSize, &ipBlock); 

 VARIANT varChunk;
 SAFEARRAY *psa;
 
 SAFEARRAYBOUND rgsabound[2];
 rgsabound[0].cElements = lWidth;
 rgsabound[0].lLbound = 0;
 rgsabound[1].cElements = lHeight;
 rgsabound[1].lLbound = 0;
 psa = SafeArrayCreate(VT_UI1,2,rgsabound);
 LPBYTE pD;
 SafeArrayAccessData(psa, (void**)&pD);
// pD = pData; 事实证明,直接这样不行,必须要经过下面赋值过程
 long index;

 CProDlg* pProDlg = new CProDlg();
 pProDlg->Create(IDD_DLG_PRO);
 pProDlg->SetWindowText("正在生成图像文件");
 pProDlg->ShowWindow(SW_SHOW);
 pProDlg->m_pro.SetRange(0, lWidth * lHeight-1);

 for(long i=0;i {
  for (long j = 0; j < lHeight; j++)
  {    
    index = i*lHeight + j;  
    pD[index] =pData[index];//i+j;
  }
  pProDlg->m_pro.SetPos(i*lHeight+j);
 }
 delete pProDlg;
 pProDlg = NULL;
 
 varChunk.vt = VT_ARRAY|VT_UI1;
 varChunk.parray = psa; 

 SafeArrayUnaccessData(psa); 
 ipBlock->put_SafeArray(0, varChunk);
  
 ipPnt->SetCoords(0,0); 
 // Write the PixelBlock to raster band
 ipRawPixel->Write(ipPnt, ipBlock);

}

小结一下,实现的过程中难点在于SAFEARRAY类型数据的使用,如果在VB或C#中不存在这个难点问题,很简单了,如果有什么问题的话,大家可以查一查SAFEARRAY它的用法或跟wzj23020723联系。

Tags:生成 栅格 AO 图像 灰度 矩阵 单波段  
责任编辑:3S_Studio
相关文章列表
没有相关文章
关于我们 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 中国地图