Создание 1bppIndexed изображения, проблемы с шагом и исключение доступа - PullRequest
0 голосов
/ 11 марта 2012

Как я могу поместить значения в массив изображения? На самом деле я не могу сделать это во всем массиве из-за bmpData.Stride. Размер хранимых байтов должен быть около 100, фактически 40.

Я получаю исключение accessviolation при использовании System.Runtime.InteropServices.Marshal.Copy.

Я использовал в примере кода из Библиотека MSDN - метод Bitmap.LockBits (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;

1 Ответ

8 голосов
/ 11 марта 2012

Format1bppIndexed означает, что есть один бит на пиксель, а не байт.Кроме того, формат BMP требует, чтобы каждая строка начиналась с четырехбайтовой границы.Отсюда 40:

  1. [строка из 10 пикселей] x [1 бит на пиксель] = 10 бит = 2 байта.
  2. Размер строки должен быть кратным 4, поэтому к каждой строке будет добавлено 4 - 2 = 2 байта.
  3. [10 строк] x [4 байта на строку] = 40 байтов.

Чтобы создать случайное изображение размером 1 бит на дюйм, вы должны переписать цикл следующим образом:

// 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...