1. 程式人生 > >將影象BYTE(unsigned char)陣列轉換為VARIANT型別

將影象BYTE(unsigned char)陣列轉換為VARIANT型別

  因為近期工作需要完成OCX控制元件同時支援C#與C++呼叫,所以介面設定就會遇上些問題。在需要將圖片的記憶體資料(buffer)傳入控制元件時,如果按照C++慣例,設計介面引數型別為unsigned char*,就會存在被C#識別為ref byte的引數,這樣就只能夠傳遞一個畫素的資料(8bit灰度影象)。

  這麼一來,就需要使介面引數型別能夠成功傳遞一個buffer陣列,那麼就想到了VARIANT型別,它可以將陣列封裝起來,包含陣列的維度與長度以及型別資訊。這樣一來就可以滿足要求了。

根據CImage類獲得影象資料(BYTE陣列):

///開啟圖片
    CImage img;
    img.Load(csName);

    ///
獲得影象資料
int pitch = img.GetPitch(); int bytes = abs(pitch) * img.GetHeight(); BYTE * src = (BYTE*)img.GetBits(); BYTE* tempBuffer = new BYTE[bytes]; int sizeLine = abs(pitch); ///這部分影象記憶體的處理將另開一篇博文詳細解釋,此處實現比較粗糙 for ( int line = 0; line < img.GetHeight(); ++line ){ memcpy(tempBuffer + line*sizeLine, src + line*pitch, sizeLine); } ///
將影象資料封裝為介面需要的VARIANT型別
VARIANT pImgBuffer; VariantInit(&pImgBuffer); SAFEARRAY *psa = NULL; SAFEARRAYBOUND rgsabound; rgsabound.cElements = bytes; rgsabound.lLbound = 0; psa = SafeArrayCreate(VT_UI1, 1, &rgsabound); if ( psa == NULL ) return; BYTE *pBitmapData = NULL;//new BYTE[bytes];(不需要new)
SafeArrayAccessData(psa, (void **)&pBitmapData); memcpy(pBitmapData, tempBuffer, bytes); ///將SAFEARRAY放入VARIANT中,並設定型別 pImgBuffer.vt = VT_ARRAY | VT_UI1; SafeArrayCopy(psa, &pImgBuffer.parray); SafeArrayUnaccessData(psa); //這裡也就不需要使用delete釋放pBitmapData所指向的空間 //YOUR_INTERFACE(pImgBuffer/*VARIANT*/, img.GetHeight(), img.GetWidth()); if ( tempBuffer ) delete[] tempBuffer; tempBuffer = NULL; SafeArrayDestroy(psa); img.Destroy();

介面內實現:

    //VARIANT* pPixArray;(介面引數)
    unsigned char* pBuffer = NULL;
    SafeArrayAccessData(pPixArray.parray, (void**)&pBuffer);

    ///此處使用pBuffer所指向的資料

    SafeArrayUnaccessData(pPixArray.parray);

    HRESULT ret = VariantClear(&pPixArray);

  該博文也就是業務程式碼稍加整理,未能仔細勘校,如有疏漏或是錯誤,請不吝賜教