2012-03-11 65 views
0

如何將值放入圖像數組中?其實我不能在整個數組中做到這一點,由於bmpData.Stride。存儲值的字節大小應該在100左右,實際上是40.創建1bpp索引圖像,步伐和accessviolationexception的問題

我在使用System.Runtime.InteropServices.Marshal.Copy時出現accessviolationexception。

我使用的代碼示例從MSDN Library - Bitmap.LockBits Method (Rectangle, ImageLockMode, PixelFormat)

爲什麼我不能寫這樣的事情?

// Declare an array to hold the bytes of the bitmap. 
     int bytes = Math.Abs(bmpData.Width) * b.Height; 

我的整個代碼是:

 //Create new bitmap 10x10 = 100 pixels 
     Bitmap b = new Bitmap(10, 10, System.Drawing.Imaging.PixelFormat.Format1bppIndexed); 

     Rectangle rect = new Rectangle(0, 0, b.Width, b.Height); 
     System.Drawing.Imaging.BitmapData bmpData = 
      b.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, 
      b.PixelFormat); 

     // Get the address of the first line. 
     IntPtr ptr = bmpData.Scan0; 

     // Declare an array to hold the bytes of the bitmap. 
     int bytes = Math.Abs(bmpData.Stride) * b.Height;//error if bmpData.Width 
     byte[] rgbValues = new byte[bytes]; 

     // Copy the RGB values into the array. 
     System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); 

     //Create random constructor 
     Random r = new Random(); 

     //Generate dots in random cells and show image 
     for (int i = 0; i < bmpData.Height; i++) 
     { 
      for (int j = 0; j < b.Width; j++) 
      { 
       rgbValues[i + j] = (byte)r.Next(0, 2); 
      } 
     } 

     // Copy back values into the array. 
     System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes); 

     // Unlock the bits. 
     b.UnlockBits(bmpData); 

     // Draw the modified image. 
     pictureBox1.Image = (Image)b; 

回答

6

Format1bppIndexed意味着有一個每像素,而不是字節。此外,BMP格式要求每行都以四字節邊界開始。這是40來自:

  1. [10像素行] x [1位每像素] = 10位= 2個字節。
  2. 行大小應該是4的倍數,所以4-2 = 2個字節將被附加到每一行。
  3. [10行]×[每行4個字節] = 40個字節。

生成隨機1bpp映射圖像,你應該重寫循環是這樣的:

// Generate dots in random cells and show image 
for (int i = 0; i < bmpData.Height; i++) 
{ 
    for (int j = 0; j < bmpData.Width; j += 8) 
    { 
     rgbValues[i * bmpData.Stride + j/8] = (byte)r.Next(0, 256); 
    } 
} 

或者只是使用的,而不是循環的Random.NextBytes方法:

r.NextBytes(rgbValues); 
+0

謝謝!現在我明白了 :) – deadfish 2012-03-11 15:45:44