【问题标题】:Creating 1bppIndexed image, trouble with stride and accessviolationexception创建 1bppIndexed 图像,步幅问题和访问违规异常
【发布时间】:2012-03-11 23:41:22
【问题描述】:

如何将值放入图像数组?实际上,由于 bmpData.Stride,我无法在整个数组中执行此操作。存储值的字节大小应该在100左右,实际上是40。

我在使用 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;

【问题讨论】:

    标签: c# image-processing marshalling access-violation


    【解决方案1】:

    Format1bppIndexed 表示每个像素有一个 bit,而不是字节。此外,BMP 格式要求每行以四字节边界开始。这就是40 的来源:

    1. [10 像素行] x [每像素 1 位] = 10 位 = 2 字节。
    2. 行大小应为 4 的倍数,因此每行将附加 4 - 2 = 2 个字节。
    3. [10 行] x [每行 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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-09
      • 1970-01-01
      • 1970-01-01
      • 2012-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多