2012-03-11 4 views
0

どのようにイメージの配列に値を入れることができますか?実際には私はbmpData.Strideのために全体の配列でそれを行うことはできません。値を格納するバイトのサイズは約100であり、実際には40です。1bppIndexedイメージの作成、ストライドとアクセス違反の問題

System.Runtime.InteropServices.Marshal.Copyを使用しているときにアクセス違反の例外が発生しました。

私はそのような何かを書くことができないのはなぜ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は、ピクセル当たり1ビット、ないバイトがあることを意味します。また、BMPフォーマットでは、各行が4バイト境界で開始する必要があります。ここで、40は、

  1. [10ピクセル行] x [1ビット/ピクセル] = 10ビット= 2バイトです。
  2. 行サイズは4の倍数である必要があります。したがって、各行に4-2 = 2バイトが追加されます。
  3. [10行]×[1行あたり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

関連する問題