『公告』 预祝您龙年大吉,万事如意, 过节期间, 大家如需数据服务,请拨打400 或直接添加客服微信,再祝大家龙年,心想事成。
关注我们 新浪 腾讯

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

用灰度矩阵在AO中生成单波段栅格图像
在VC中定义矩阵,然后填充灰度矩阵,有了值后,就可以生成一幅栅格图像。同样可以读取已有的图像数据,修改之,或处理、计算等生成别的图像等。

       开门见山,先把这个函数拿出来,看函数实现之前,我想先说一说各参数。

       1szPath是生成的栅格的路径

       2szFile是生成的栅格的文件名

       3rstInfoRasterInfo结构体变量,是生成栅格的一些参数信息

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;

 };

};

       4pData是一个BYTE**(LPBYTE)类型的数组,

       5szRasFormat是栅格类型枚举,其定义为

enum RasterFormat

{

 IMAGINE_Image,

 TIFF,

 GRID

};

       6bNoDataValue是透明灰度值,不过现在我还没有研究明白,实现不了效果,哪们朋友研究清楚了,可以指点一下。

//下面才是真正的函数开始了。

//生成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类型数据的使用,如果在VBC#中不存在这个难点问题,很简单了,如果有什么问题的话,大家可以查一查SAFEARRAY它的用法或跟wzj23020723联系。

      京ICP备2025132830号-1 京公网安备 号