C# Изменить байтовый массив и преобразовать в изображение - PullRequest
0 голосов
/ 25 марта 2020

В приведенном ниже коде я хочу преобразовать изображение в байтовый массив, изменить значение некоторых пикселей и преобразовать его обратно в изображение. Все работает нормально, если я не изменяю значение пикселя. Два преобразования работают. Но если я пытаюсь изменить значение пикселя между двумя преобразованиями, я получаю исключение. Можете ли вы сказать мне, что я делаю неправильно?

        OpenFileDialog openFileDialog = new OpenFileDialog();
        openFileDialog.ShowDialog();
        FileStream bmpstream = new FileStream(openFileDialog.FileName, FileMode.Open, FileAccess.Read);
        Bitmap spotImage = new Bitmap(bmpstream);

        ImageConverter imgCon = new ImageConverter();
        byte[] rgbValues = (byte[])imgCon.ConvertTo(spotImage, typeof(byte[]));

        for (int counter = 2; counter < rgbValues.Length; counter += 3)
        {    

            Buffer.SetByte(rgbValues, counter, 0x00);
            //rgbValues[counter] = 0x00; <--I tried also this (not sure of the difference) and I get the same result

        }

        Image image2 = null;
        using (MemoryStream mStream = new MemoryStream(rgbValues, 0, rgbValues.Length))
        {

                image2 = Image.FromStream(mStream, true); //this line gives the exception

        }
        pictureBox2.Image = image2;

Я также попытался открыть файл с помощью Bitmap.LockBits и получил тот же результат. Вот вторая версия кода (опять же, он работал, пока я не модифицировал байтовый массив):

        Rectangle rect = new Rectangle(0, 0, spotImage.Width, spotImage.Height);
        BitmapData bmpData = spotImage.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, spotImage.PixelFormat);
        IntPtr pointeur = bmpData.Scan0;
        int bytes = Math.Abs(bmpData.Stride) * bmpData.Height;
        byte[] rgbValues = new byte[bytes];
        System.Runtime.InteropServices.Marshal.Copy(pointeur, rgbValues, 0, bytes);
        for (int counter = 2; counter < rgbValues.Length; counter += 3)
        {

            Buffer.SetByte(rgbValues, counter, 0x00);
            //rgbValues[counter] = 0x00;

        }
        spotImage.UnlockBits(bmpData);


        Image image2 = null;
        using (MemoryStream mStream = new MemoryStream(rgbValues, 0, rgbValues.Length))
        {

                image2 = Image.FromStream(mStream, true); //this line gives the exception

        }
        pictureBox2.Image = image2;

1 Ответ

0 голосов
/ 25 марта 2020

Обе ваши попытки не увенчались успехом, потому что, как в комментариях:

  1. Первая попытка - вы перепутали байты в заголовке файла
  2. Вторая попытка - вы пытаетесь декодировать необработанные данные пикселей как Image

Ваша вторая попытка гораздо ближе к правильному решению. Блокируйте биты с включенной записью и оставайтесь с изображением, которое вы уже открыли - не нужно перестраивать новое растровое изображение (если на самом деле есть такая необходимость в вашем конкретном случае c, тогда я оставлю это вам в качестве упражнения):

OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.ShowDialog();
FileStream bmpstream = new FileStream(openFileDialog.FileName, FileMode.Open, FileAccess.Read);
Bitmap spotImage = new Bitmap(bmpstream);

Rectangle rect = new Rectangle(0, 0, spotImage.Width, spotImage.Height);
BitmapData bmpData = spotImage.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, spotImage.PixelFormat);
IntPtr pointeur = bmpData.Scan0;
int bytes = Math.Abs(bmpData.Stride) * bmpData.Height;
byte[] rgbValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(pointeur, rgbValues, 0, bytes);

var pixelSize = Image.GetPixelFormatSize(bmpData.PixelFormat);

for (int counter = 2; counter < rgbValues.Length; counter += 3)
{
    rgbValues[counter] = 0x00;
}
// copy buffer back to image
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, pointeur, bytes);

spotImage.UnlockBits(bmpData);

pictureBox2.Image = spotImage;

Это должно работать. Я не знаю, какое влияние на изображение вы хотели достичь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...