Click here to Skip to main content
15,890,670 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to convert a Bitmap image into a 2D array of integers and vice versa.

I have written the given code.

And, this is my driver program:

C#
private void forwardFftButton_Click(object sender, EventArgs e)
        {
            Bitmap grayscale = (Bitmap) GrayscaleUtils.ColorToGrayscale(inputImagePictureBox.Image);

            grayscaleImagePictureBox.Image = grayscale;

            int[,] array2D = ImageDataConverter.BitmapToArray2D(grayscale);

            Bitmap grayScaleAgain = ImageDataConverter.Array2DToBitmap(array2D);

            processedImagePictureBox.Image = grayScaleAgain;
        }




This is the result:[^]

The conversion isn't working.

What is the bug in my code?

What I have tried:

C#
using System;
using System.Drawing;
using System.Drawing.Imaging;

public partial class ImageDataConverter
{
	public static int[, ] BitmapToArray2D(Bitmap image)
	{
		int[, ] array2D = null;
		if (image.PixelFormat == PixelFormat.Format8bppIndexed)
		{
			array2D = new int[image.Width, image.Height];
			BitmapData bitmapData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
			int paddingOffset = bitmapData.Stride - (bitmapData.Width * 1); //1 == 1-byte per pixel
			unsafe
			{
				byte *memoryAddress = (byte *)bitmapData.Scan0;
				for (int i = 0; i < bitmapData.Width; i++)
				{
					for (int j = 0; j < bitmapData.Height; j++)
					{
						byte tempByte = memoryAddress[0];
						array2D[i, j] = (int)tempByte;
						int tempArrayElement = array2D[i, j];
						//1-byte per pixel
						memoryAddress += 1;
					}

					memoryAddress += paddingOffset;
				}
			}

			image.UnlockBits(bitmapData);
		}
		else
		{
			throw new Exception("8 bit/pixel indexed image required.");
		}

		return array2D;
	}

	public static Bitmap Array2DToBitmap(int[, ] image)
	{
		Bitmap output = new Bitmap(image.GetLength(0), image.GetLength(1));
		BitmapData bitmapData = output.LockBits(new Rectangle(0, 0, image.GetLength(0), image.GetLength(1)), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
		int paddingOffset = bitmapData.Stride - (bitmapData.Width * 1); //1 == 1-byte per pixel
		unsafe
		{
			byte *memoryAddress = (byte *)bitmapData.Scan0;
			for (int i = 0; i < bitmapData.Height; i++)
			{
				for (int j = 0; j < bitmapData.Width; j++)
				{
					int tempInt = image[j, i];
					memoryAddress[0] = (byte)tempInt;
					byte tempByte = memoryAddress[0];
					//1-byte per pixel
					memoryAddress += 1;
				}

				memoryAddress += paddingOffset;
			}
		}

		output.UnlockBits(bitmapData);
		return output;
	}
}
Posted
Updated 10-Jul-16 11:37am
v2

1 solution

You should learn to use the debugger as soon as possible. Rather than guessing what your code is doing, It is time to see your code executing and ensuring that it does what you expect.

The debugger allow you to follow the execution line by line, inspect variables and you will see that there is a point where it stop doing what you expect.
Debugger - Wikipedia, the free encyclopedia[^]
Mastering Debugging in Visual Studio 2010 - A Beginner's Guide[^]

Make sure you don't loose data in type conversion.
Make sure you don't skip data.
Make sure the bitmapdata match your expectations.
 
Share this answer
 
Comments
[no name] 10-Jul-16 20:30pm    
The bug isn't in the code. The bug is in the logic.
Patrice T 10-Jul-16 21:22pm    
The code match the logic.
[no name] 11-Jul-16 15:06pm    
Okay.

I have solved the problem.

//Working correctly.
public static int[,] BitmapToArray2D(Bitmap image)
{
int[,] array2D = new int[image.Width, image.Height];

BitmapData bitmapData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadWrite,
PixelFormat.Format32bppRgb);

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

int paddingOffset = bitmapData.Stride - (image.Width * 4);//4 bytes per pixel

for (int i = 0; i < image.Width; i++)
{
for (int j = 0; j < image.Height; j++)
{
byte[] temp = new byte[4];
temp[0] = address[0];
temp[1] = address[1];
temp[2] = address[2];
temp[3] = address[3];
array2D[i, j] = BitConverter.ToInt32(temp, 0);
////array2D[i, j] = (int)address[0];

//4 bytes per pixel
address += 4;
}

address += paddingOffset;
}
}
image.UnlockBits(bitmapData);

return array2D;
}


//Working Correctly
public static Bitmap Array2DToBitmap(int[,] integers)
{
int width = integers.GetLength(0);
int height = integers.GetLength(1);

int stride = width * 4;//int == 4-bytes

Bitmap bitmap = null;

unsafe
{
fixed (int* intPtr = &integers[0, 0])
{
bitmap = new Bitmap(width, height, stride, PixelFormat.Format32bppRgb, new IntPtr(intPtr));
}
}

return bitmap;
}
Patrice T 11-Jul-16 17:41pm    
Nice to hear it.
How did you understood what was the problem ? debugger as I told you ?

You can post the code as a solution and tell us what was the problem

From there, I guess 1D is not complicated.
[no name] 12-Jul-16 9:21am    
In my previous code, there was a mismatch of PixelFormat and number of channels.

For instance, I was using the pixel format Format32bppRgb but was using 1 channel, etc.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900