User 6976447 Ответов: 1

Как я могу преобразовать растровое изображение в 2D-массив целых чисел и наоборот в C#?


Я хочу преобразовать растровое изображение в 2D-массив целых чисел и наоборот.

Я написал данный код.

И это моя программа драйвера:

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




Таков результат:[^]

Преобразование не работает.

Что это за ошибка в моем коде?

Что я уже пробовал:

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

1 Ответов

Рейтинг:
1

Patrice T

Вы должны научиться использовать отладчик как можно скорее. Вместо того чтобы гадать, что делает ваш код, пришло время увидеть, как он выполняется, и убедиться, что он делает то, что вы ожидаете.

Отладчик позволяет вам следить за выполнением строка за строкой, проверять переменные, и вы увидите, что есть точка, в которой он перестает делать то, что вы ожидаете.
Отладчик-Википедия, свободная энциклопедия[^]
Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]

Убедитесь, что вы не теряете данные при преобразовании типов.
Убедитесь, что вы не пропускаете данные.
Убедитесь, что растровые данные соответствуют вашим ожиданиям.


[no name]

Ошибка не в коде. Ошибка в логике.

Patrice T

Код соответствует логике.

[no name]

Окей.

Я решил эту проблему.

// Работает правильно.
public static int [,] BitmapToArray2D(растровое изображение)
{
int [,] array2D = new int[image.Ширина, изображение.Высота];

BitmapData bitmapData = изображение.LockBits (новый прямоугольник (0, 0, изображение.Ширина, изображение.Высота),
ImageLockMode.Чтение и запись,
PixelFormat.Format32bppRgb);

небезопасный
{
byte* address = (byte*)bitmapData.Scan0;

инт paddingOffset = метод BitmapData.Шаг - (изображение.Ширина * 4);//4 байта на пиксель

for (int i = 0; i & lt; image.Ширина; i++)
{
for (int j = 0; j < image.Высота; j++)
{
byte [] temp = новый байт[4];
temp[0] = Адрес[0];
temp[1] = Адрес[1];
temp[2] = Адрес[2];
temp[3] = Адрес[3];
array2D[i, j] = BitConverter.ToInt32(temp, 0);
////array2D[i, j] = (int)адрес[0];

//4 байта на пиксель
адрес += 4;
}

адрес += paddingOffset;
}
}
изображение.UnlockBits(bitmapData);

return array2D;
}


// Работает Правильно
public static Bitmap Array2DToBitmap(int[,] integers)
{
int width = целые числа.Метода getlength может служить метод(0);
int height = целые числа.Метода getlength может служить метод(1);

int stride = width * 4;/ / int == 4-байта

Растровое изображение растровое изображение = нуль;

небезопасный
{
fixed (int* intPtr = & amp;integers[0, 0])
{
bitmap = новое растровое изображение (ширина, высота, шаг, Пиксельформат.Format32bppRgb, новый IntPtr(intPtr));
}
}

возврат растрового изображения;
}

Patrice T

Приятно это слышать.
Как вы поняли, в чем была проблема ? отладчик, как я вам уже говорил ?

Вы можете опубликовать код в качестве решения и рассказать нам, в чем была проблема

Оттуда, я думаю, 1D не является сложным.

[no name]

В моем предыдущем коде было несоответствие Пиксельформата и количества каналов.

Например, я использовал пиксельный формат Format32bppRgb, но использовал 1 канал и т. д.

Patrice T

Так что проблема решена.

[no name]

Видимо, так. :)