2011-10-15 57 views
3

我必須將我的C++項目與C#項目進行接口,並通過命名管道將圖像發送給它。 OpenCV將矩陣數據存儲在一個連續的塊中,從uchar* Mat::data開始。但是,要通過命名管道發送數據,它必須是char*,所以我只是做一個演員,不知道我應該做什麼。它應該不重要,它只是數據,而不是字符。從char []緩衝區在C#中創建位圖

size_t s = frame2.elemSize() * frame2.rows * frame2.cols; 
sendChars(hPipe, (char*)frame2.data, s); 

在C#端我讀取數據塊到char[]緩衝區。然後用適當的寬度,高度等創建一個新的Bitmap,並將IntPtr設置爲char[] buffer的開頭。

//in the C# forms private scope: 
    char[] buffer = new char[921600]; 

,然後在StartServer()功能:

pipeServer = new NamedPipeServerStream("SamplePipe", PipeDirection.InOut); 
    //blah blah blah 
    using (StreamReader sr = new StreamReader(pipeServer)) 
    { 
     sr.ReadBlock(buffer, 0, buffer.Length); 
     unsafe 
     { 
      fixed (char* ptr = buffer) 
      { 
       using (Bitmap image = new Bitmap(640, 480, 640*3, PixelFormat.Format24bppRgb, new IntPtr(ptr))) 
       { 
        pictureBox1.Image = image; 
        image.Save("test.png"); 
       } 
      } 
     } 
    } 

這樣做的結果是C#窗體上的大紅色的X和保存的圖像看起來亂碼...但不只是隨機噪聲。因此,數據在傳輸之前就已經通過了C++端,或者C#在解釋端結束了。我試圖通過使用Bitmap構造函數來解決這個問題,該構造函數讀取流併發送編碼圖像而不是原始像素,但是比上述方法(僅給出錯誤,沒有輸出)更難。

what it looks like

如何轉移UCHAR *陣列與來自C++到C#的像素數據,然後重構它一個位圖內,這樣我可以在表單上顯示呢?

+0

你需要弄清楚你的數據類型。 C++中的'unsigned char'是C#中的'byte'; C#中的'char'是C++中的'wchar_t'。 – ildjarn

回答

6

這裏使用StreamReader似乎是錯誤的選擇,如果您發送的內容實際上是二進制數據。 StreamReader用於讀取文本,並將數據解碼爲一些編碼的字符,在您的情況下會自動檢測(肯定是錯誤的)。

您要使用的BinaryReader用於讀取二進制數據,或使用Read()方法獲取byte[]陣列直接從NamedPipeServerStream讀取。 C#中的char用於存儲字符,並且是unicode,而不是單個字節。

+0

謝謝,沒有意識到StreamReader是用於文本的-__- – Jim

+0

不客氣。它的名字肯定會更好,但它實際上是從'TextReader'類繼承而來的,儘管這可能不是第一個尋找的東西。 ;) – DeCaf

0

如果使用流,最簡單的方法是使用位圖的SetPixel方法構造圖像。

+1

這會非常慢。每個SetPixel調用都必須一次鎖定和解鎖整個位圖表面一個像素。 – asawyer