2011-02-24 46 views
0

這是我從here收集的一段代碼。C中的倒像#

private unsafe byte[] BmpToBytes_Unsafe(Bitmap bmp) 

     { 

      BitmapData bData = bmp.LockBits(new Rectangle(0,0,1000,1000), 

       ImageLockMode.ReadOnly, 

       PixelFormat.Format24bppRgb); 

      // number of bytes in the bitmap 



      int byteCount = bData.Stride * bmp.Height; 

      byte[] bmpBytes = new byte[byteCount]; 



      // Copy the locked bytes from memory 





      Marshal.Copy(bData.Scan0, bmpBytes, 0, byteCount); 

      Marshal. 



      // don't forget to unlock the bitmap!! 

      bmp.UnlockBits(bData); 



      return bmpBytes; 

     } 

我有一個函數,從上面提到的函數獲取字節,只是顯示它沒有進一步處理。但是我得到了輸出的倒像。有人可以解釋嗎?

回答

1

當你說「倒置」時,我想你的意思是倒過來?

你不能依賴發佈該代碼的人的「l33t hax0r skillz」。他缺乏關於位圖在內存中如何處理的一些重要信息。

當您從位圖中讀取數據時,無法在一個塊中讀取所有數據。數據以行存儲,並且行可以首先存儲在頂行或底行。此外,可能會在行之間填充字符以獲得每個行的偶數字邊界。

Scan0屬性是指向第一行開頭的指針,Stride屬性是下一行開始的偏移量。 Width屬性可用於確定每行中有多少數據。

所以,你必須將數據一行一次複製:

int lineSize = bData.Width * 3; 
int byteCount = lineSize * bData.Height; 
byte[] bmpBytes = new byte[byteCount]; 

IntPtr scan = bData.Scan0; 
for (int i = 0; i < bData.Height; i++) { 
    Marshal.Copy(scan, bmpBytes[i * lineSize], 0, lineSize); 
    scan += bData.Stride; 
} 
+0

快速注意,這種方法是從一個線程調用,只有一個線程正在訪問此方法。你認爲這種方法需要線程安全嗎? – nightWatcher 2011-02-24 07:53:00

+0

@nightWatcher:如果只有一個線程調用該方法,則不需要使線程安全。 – Guffa 2011-02-24 08:50:13

1

這是正常的,位圖存儲顛倒。底部掃描線位於BitmapData.Scan0。您需要更正此問題,可能是通過一次複製一條掃描線。取決於你如何顯示它。

0

24 bpp窗口位圖內部保持BGR順序的像素顏色,而不是RGB。