-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");
        }
    }

The exception in the following line:

 iii = (int)(*address);

An unhandled exception of type 'System.AccessViolationException' occurred in Fast Fourier Transform.exe

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

enter image description here

What is the cause of that exception?

How can I fix that?

.

.

P.S. I am using the following PNG image:

enter image description here

user366312
  • 16,949
  • 65
  • 235
  • 452
  • To directly use pointers, you have to declare the code section as unsafe. – Kevin Aug 04 '16 at 18:08
  • @Kevin, I have already declared it as unsafe. Otherwise, it shouldn't have been running. – user366312 Aug 04 '16 at 18:09
  • Can you post an example picture? Because for me the code is working fine – technikfischer Aug 04 '16 at 18:09
  • @technikfischer, done! take a look, plz. – user366312 Aug 04 '16 at 18:13
  • How do you load the image? Because using this image the code tells me that it is not grayscale. Or which file format is the original file? – technikfischer Aug 04 '16 at 18:23
  • @technikfischer, https://dotnetfiddle.net/6J03D3 – user366312 Aug 04 '16 at 18:34
  • @technikfischer, I converted it to Grayscale. See the fiddle link. – user366312 Aug 04 '16 at 18:35
  • public class BitmapToIntegerAndViceVersa__Test { private static string path = @"scratch.png"; public static void Run() { Bitmap scratch = Bitmap.FromFile(path) as Bitmap; int[,] integer = Grayscale.ToGrayscaleInteger(scratch); //int[,] integer = ImageDataConverter.ToInteger(grayscale); Bitmap bitmap = ImageDataConverter.ToBitmap(integer); PictureBoxForm p = new PictureBoxForm(scratch, bitmap); p.ShowDialog(); } } – user366312 Aug 04 '16 at 18:35
  • I added a answer, if it works for you, please mark it as solution – technikfischer Aug 04 '16 at 18:50

1 Answers1

3

You have mistaken bitmap.Width for bitmap.Height in your loops. You should iterate over the height in the outer loop and over the width in the inner loop, as the stride represents the whole width + the offset of the image. Then you can add padding on a line basis, instead for each line traversed. So

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

is working. Also, you must swap the array access from array2d[i, j] = iii to array2d[j, i] = iii as the indices are now belonging to the other dimension of the image

  • 1
    Also, as a general rule, when looping over x and y... _call the loop variables `x` and `y`_. It makes code a lot more straightforward. – Nyerguds Jan 10 '18 at 11:32