Подтвердить что ты не робот

Как создать битмап из массива байтов?

Я искал весь вопрос об массиве байтов, но я всегда терпел неудачу. Я никогда не кодировал С#, я новичок в этой стороне. Не могли бы вы помочь мне сделать файл изображения из массива байтов.

Вот моя функция, которая хранит байт в массиве с именем imageData

public void imageReady( byte[] imageData, int fWidth, int fHeight))
4b9b3361

Ответ 1

Ребята благодарим вас за помощь. Я думаю, что все эти ответы работают. Однако я думаю, что мой массив байтов содержит сырые байты. Вот почему все эти решения не работали для моего кода.

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

static byte[] PadLines(byte[] bytes, int rows, int columns) {
   int currentStride = columns; // 3
   int newStride = columns;  // 4
   byte[] newBytes = new byte[newStride * rows];
   for (int i = 0; i < rows; i++)
       Buffer.BlockCopy(bytes, currentStride * i, newBytes, newStride * i, currentStride);
   return newBytes;
 }

 int columns = imageWidth;
 int rows = imageHeight;
 int stride = columns;
 byte[] newbytes = PadLines(imageData, rows, columns);

 Bitmap im = new Bitmap(columns, rows, stride, 
          PixelFormat.Format8bppIndexed, 
          Marshal.UnsafeAddrOfPinnedArrayElement(newbytes, 0));

 im.Save("C:\\Users\\musa\\Documents\\Hobby\\image21.bmp");

Эти решения работают для 8 бит 256 бит/с (Format8bppIndexed). Если ваше изображение имеет другой формат, вы должны изменить PixelFormat.

И есть проблема с цветами прямо сейчас. Как только я решил это, я отредактирую свой ответ для других пользователей.

* PS = Я не уверен в значении шага, но для 8 бит он должен быть равен столбцам.

А также эта функция работает для меня. Эта функция копирует 8-битное изображение в оттенках серого в 32-битный макет.

public void SaveBitmap(string fileName, int width, int height, byte[] imageData)
        {

            byte[] data = new byte[width * height * 4];

            int o = 0;

            for (int i = 0; i < width * height; i++)
            {
                byte value = imageData[i];


                data[o++] = value;
                data[o++] = value;
                data[o++] = value;
                data[o++] = 0; 
            }

            unsafe
            {
                fixed (byte* ptr = data)
                {

                    using (Bitmap image = new Bitmap(width, height, width * 4,
                                PixelFormat.Format32bppRgb, new IntPtr(ptr)))
                    {

                        image.Save(Path.ChangeExtension(fileName, ".jpg"));
                    }
                }
            }
        }

Ответ 2

Вам нужно получить те bytes в MemoryStream:

Bitmap bmp;
using (var ms = new MemoryStream(imageData))
{
    bmp = new Bitmap(ms);
}

Это использует перегрузку конструктора Bitmap(Stream stream).

ОБНОВЛЕНИЕ: помните, что в соответствии с документацией и исходным кодом, который я читал, на этих условиях будут выбраны ArgumentException:

stream does not contain image data or is null.
-or-
stream contains a PNG image file with a single dimension greater than 65,535 pixels.

Ответ 3

Может быть так же просто, как:

var ms = new MemoryStream(imageData);
System.Drawing.Image image = Image.FromStream(ms);

image.Save("c:\\image.jpg");

Тестирование:

byte[] imageData;

// Create the byte array.
var originalImage = Image.FromFile(@"C:\original.jpg");
using (var ms = new MemoryStream())
{
    originalImage.Save(ms, ImageFormat.Jpeg);
    imageData = ms.ToArray();
}

// Convert back to image.
using (var ms = new MemoryStream(imageData))
{
    Image image = Image.FromStream(ms);
    image.Save(@"C:\newImage.jpg");
}