【问题标题】:Bitmap to Integer routine generating exception位图到整数例程生成异常
【发布时间】:2016-08-04 17:11:34
【问题描述】:
    public static bool IsGrayscale(Bitmap bitmap)
    {
        return bitmap.PixelFormat == PixelFormat.Format8bppIndexed ? true : false;
    }

.

    public static int[,] ToInteger(Bitmap image)
    {
        if (Grayscale.IsGrayscale(image))
        {
            Bitmap bitmap = (Bitmap)image.Clone();

            int[,] array2d = new int[bitmap.Width, bitmap.Height];

            BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                                                     ImageLockMode.ReadWrite,
                                                     PixelFormat.Format8bppIndexed);
            int bytesPerPixel = sizeof(byte);

            unsafe
            {
                byte* address = (byte*)bitmapData.Scan0;

                int paddingOffset = bitmapData.Stride - (bitmap.Width * bytesPerPixel);

                for (int i = 0; i < bitmap.Width; i++)
                {
                    for (int j = 0; j < bitmap.Height; j++)
                    {
                        int iii = 0;

                        //If there are more than 1 channels...
                        //(Would actually never occur)
                        if (bytesPerPixel >= sizeof(int))
                        {
                            byte[] temp = new byte[bytesPerPixel];

                            //Handling the channels.
                            //PixelFormat.Format8bppIndexed == 1 channel == 1 bytesPerPixel == byte
                            //PixelFormat.Format32bpp       == 4 channel == 4 bytesPerPixel == int
                            for (int k = 0; k < bytesPerPixel; k++)
                            {
                                temp[k] = address[k];
                            }

                            iii = BitConverter.ToInt32(temp, 0);
                        }
                        else//If there is only one channel:
                        {
                            iii = (int)(*address);
                        }

                        array2d[i, j] = iii;

                        address += bytesPerPixel;
                    }

                    address += paddingOffset;
                }
            }

            bitmap.UnlockBits(bitmapData);

            return array2d;
        }
        else
        {
            throw new Exception("Not a grayscale");
        }
    }

以下行中的异常:

 iii = (int)(*address);

“System.AccessViolationException”类型的未处理异常 发生在 Fast Fourier Transform.exe 中

附加信息:试图读取或写入受保护的内存。 这通常表明其他内存已损坏。

该异常的原因是什么?

我该如何解决这个问题?

.

.

P.S.我使用的是以下PNG图片:

【问题讨论】:

  • 要直接使用指针,你必须将代码段声明为不安全的。
  • @Kevin,我已经宣布它是不安全的。否则,它不应该一直在运行。
  • 你能发一个示例图片吗?因为对我来说代码运行良好
  • @technikfischer,完成!请看一下。
  • 如何加载图片?因为使用此图像,代码告诉我它不是灰度的。或者原始文件是哪种文件格式?

标签: c# exception image-processing bitmap bitmapdata


【解决方案1】:

您在循环中将bitmap.Width 误认为bitmap.Height。您应该迭代外循环的高度和内循环的宽度,因为步幅代表整个宽度 + 图像的偏移量。然后,您可以逐行添加padding,而不是为遍历的每一行添加。所以

for (int i = 0; i < bitmap.Height; i++)
{
    for (int j = 0; j < bitmap.Width; j++)
    {

正在工作。此外,您必须将数组访问从 array2d[i, j] = iii 交换为 array2d[j, i] = iii,因为索引现在属于图像的另一个维度

【讨论】:

  • 此外,作为一般规则,当循环 x 和 y 时...调用循环变量 xy。它使代码更直接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-24
  • 1970-01-01
  • 1970-01-01
  • 2013-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多