2016-08-04 29 views
-1
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' 的未处理的异常发生在快速傅立叶Transform.exe

其他信息:试图读或写保护的内存。 这通常表示其他内存已损坏。

enter image description here

什么是异常的原因是什么?

我该如何解决这个问题?

P.S.我使用下面的PNG图像:

enter image description here

+0

要直接使用指针,必须将代码段声明为不安全。 – Kevin

+0

@凯文,我已经宣布它不安全。否则,它不应该运行。 – anonymous

+0

你可以发布示例图片吗?因为对我来说代码工作正常 – technikfischer

回答

2

你误会了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,因为索引现在属于图像的其他维度

+0

此外,作为一般规则,在循环x和y时... _call循环变量'x'和'y'_ 。它使代码更直接。 – Nyerguds