2011-04-28 217 views
1

我正在使用C#中的一些圖像處理代碼。因爲性能至關重要,所以我在使用指針的不安全代碼中執行此操作。在C#中創建指針數組

下面是一些代碼先於我的問題:

Rectangle Image_Rectangle = new Rectangle(0, 0, MyImage.Width, MyImage.Height); 
BitmapData Image_Data = MyImage.LockBits(Image_Rectangle, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 
// ... x and y nested for-loops to work with each pixel 
Byte* PixelRow = (Byte*)Image_Data.Scan0 + (y * Image_Data.Stride); 

一旦我有以上字節的指針,我可以設置像這樣的價值觀:

PixelRow[(x * 3) + 2] = 255; 
PixelRow[(x * 3) + 1] = 255; 
PixelRow[(x * 3)] = 255; 

不過,我更願意訪問這些作爲一個陣列:

Byte[] RGB = { PixelRow[(x * PIXEL_SIZE) + 2], PixelRow[(x * PIXEL_SIZE) + 1], PixelRow[(x * PIXEL_SIZE) + 0] }; 

RGB[0] = 255; 
RGB[1] = 255; 
RGB[2] = 255; 

問題是當我嘗試賦值,我感覺我不工作w ith實際指針了。一旦我解鎖位,結果位圖不變(使用數組方法時)。

我很新的指針,任何人都可以幫助解釋發生了什麼以及如何通過使用數組正確維護指針?

+0

您確定您沒有重新發明輪子嗎? – 2011-04-28 01:41:21

+1

我還沒有在C#中使用過指針,但是我的懷疑是你遇到了捕獲指針與指向值的問題。訪問可能的第一種方法是因爲它正在計算內存地址,然後在該位置設置值255。在第二種風格中,我相信它是取消引用指針並將值存儲在新的Byte數組中。所以當你設置這個值的時候,你將它設置爲堆棧中的存儲副本,而不是你想改變的堆上的實際內存。 – Clayton 2011-04-28 01:45:03

回答

1
Byte[] RGB = { PixelRow[(x * PIXEL_SIZE) + 2], 
       PixelRow[(x * PIXEL_SIZE) + 1], 
       PixelRow[(x * PIXEL_SIZE) + 0] }; 

您創建一個基於PixelRow[..]所指向的值的字節數組 - 因爲這些字節 - 值類型 - 你正在爲每個字節創建一個副本,並且生成的陣列與它們來自的映像完全分離。

1

猜你不能在離開註釋代碼:) 試着這麼做

Byte*[] RGB = { &PixelRow[(x * PIXEL_SIZE) + 2], 
       &PixelRow[(x * PIXEL_SIZE) + 1], 
       &PixelRow[(x * PIXEL_SIZE) + 0] }; 

--4/29編輯

你可以嘗試另一種方法是獲得一個指向索引您所關注像素的陣列開始。然後用數組表示法來訪問和修改你所關心的紅,綠和藍字節值。現在假定像素按順序存儲在陣列中,但您可以按如下方式進行操作:

Byte* RGB = &PixelRow[x * PIXEL_SIZE]; 
RGB[0] = (byte)255; 
RGB[1] = (byte)255; 
RGB[2] = (byte)255; 
+0

不幸的是,這沒有奏效,試圖分配一個像這樣的值'RGB [0] = 255;'導致錯誤(不能將int轉換爲字節*)。 – JYelton 2011-04-28 19:12:16

+0

您可能必須取消引用數組中的指針才能設置值。試試看: * RGB [0] =(byte)255; – Clayton 2011-04-29 15:27:22

+0

@JYelton你能在這裏工作嗎?我在LinqPad做了一些測試,我的兩種方法都適用於我。 – Clayton 2011-07-13 05:38:29