Независимый от устройства байтовый массив для изображения: параметр недействителен

Я работаю с электронным программным обеспечением OMICRON MPD и MI, которое обеспечивает интерфейс COM. Я делаю снимок экрана с помощью методов, предоставляемых COM-интерфейсом, и пытаюсь сохранить байт [] в файл изображения.

Мой код:

byte[] rawImg = ...
MemoryStream mstream = new MemoryStream(rawImg);
ImageConverter imageConverter = new System.Drawing.ImageConverter();
System.Drawing.Image image = imageConverter.ConvertFrom(rawImg) as System.Drawing.Image; //error line
image.Save(@"path\img.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);

Я получаю ошибку:

System.ArgumentException' occurred in System.Drawing.dll Parameter is not valid

Я проверил длину байтового массива:

rawImg.Length
//897832

Я могу сохранить вышеуказанный поток памяти в файл, используя следующее:

using (FileStream file = new FileStream(@"path\img.txt", FileMode.Create, FileAccess.Write))
{
    mstream.WriteTo(file);
}

Я не уверен, что это значит, но как мне отладить это? Где ошибка? Это ошибочные данные, которые я получаю, или код C# для сохранения их в виде изображения.

Согласно документации интерфейса COM, rawImg является независимым от устройства растровым изображением (формат идентичен файлу.BMP).

Неудачная попытка № 1

ImageConverter imageConverter = new System.Drawing.ImageConverter();
            Image image = imageConverter.ConvertFrom(rawImg) as Image; //error line
            image.Save(@"path\img.bmp", System.Drawing.Imaging.ImageFormat.Bmp);

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

Окончательное решение

Я смотрю видео под названием "Hex To BMP: Создание растрового изображения с нуля", которое помогло мне построить изображение на основе полученных данных.

Я получал данные, которые содержали данные изображения в байтах, 40-байтовый заголовок DIB и некоторые начальные 27 байтов данных (я не мог понять, что это такое). Для того, чтобы это было переведено в изображение, в начале ему понадобился 14-байтовый заголовок файла, который я вручную построил так:

byte[] fileHeader = { 0x42, 0x4d, 0x0c, 0xef, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00 };

Обратите внимание, что размер файла в шестнадцатеричном формате (0x0c, 0xef, 0x82, 0x00, что равняется размеру файла 847760 байт) жестко запрограммирован (байт можно легко сделать динамическим). 0x36 - это то место, где начинаются фактические данные изображения. Индекс 54 равен 36 в шестнадцатеричном формате.

Затем я просто добавил эти данные из моего исходного массива, сместив туда, где начинается заголовок DIB, который в моем случае был индекс 27.

Ниже приведен скриншот моих необработанных данных с начальными 27 байтами неизвестных данных и с заголовком DIB, начинающимся с индекса 27.

Выше скриншот моих шестнадцатеричных данных окончательного изображения. Синий - это заголовок файла из 14 байтов, красный - это 40-байтовый заголовок DIB, а остальное, начиная с зеленого, - это данные изображения. Сохраните эти данные с расширением ".bmp", и вы получите изображение.

Мой код:

byte[] imgData, newImgData;
byte[] fileHeader = { 0x42, 0x4d, 0x0c, 0xef, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00 };
newImgData = new byte[847760];
BinaryFormatter bf = new BinaryFormatter();
string path2 = @"path\myImg.bmp";
using (MemoryStream ms = new MemoryStream())
{
  bf.Serialize(ms, value);
  mgData = ms.ToArray();

 }
 for(int i = 0; i < fileHeader.Count(); i++)
 {
       newImgData[i] = fileHeader[i];
 }

  int indx = 14;

  for (int i = 27; i < imgData.Count(); i++)
  {
       newImgData[indx] = imgData[i];
       indx++;
  }

  System.IO.File.WriteAllBytes(path2, newImgData.ToArray());

2 ответа

Глядя на дамп Notepad++, кажется, что это всего лишь необработанные байты 32-битного или 4-байтового ARGB-изображения. Вы должны быть в состоянии использовать Bitmap(Int32, Int32, Int32, PixelFormat, IntPtr) конструктор и просто передать в необработанных байтах. Единственная проблема будет выяснить width, height, stride, а также PixelFormat изображения, но вы должны быть в состоянии понять это с небольшим количеством экспериментов.

Вот пример, где я сделал байтовый массив, похожий на тот, который вы показали:

byte[] bytes = new byte[] {
    0,64,128,128,
    0,64,128,128,
    0,64,128,128,
    0,64,128,128,
    0,64,128,128,
    0,64,128,128,
    0,64,128,128,
    0,64,128,128,
};

unsafe
{
    fixed (byte* pBytes = bytes)
    {
        int width = 4; // Your width
        int height = 2; // Your height
        int stride = width * 4; // Your stride
        Bitmap bitmap = new Bitmap(width, height, stride, PixelFormat.Format32bppArgb, new IntPtr(pBytes));
        bitmap.Save(@"c:\temp\bitmap.png"); // Could save to another format like .jpg
    }
}

Попробуйте просто вместо своего фрагмента кода что-то вроде этого:

byte[] rawImg = ...

MemoryStream mstream = new MemoryStream(rawImg);
File.WriteAllBytes("screen.bmp", mstream.ToArray());

Попытка № 2

Мое второе предположение, что это может быть формат файла DIB, если это правда, вы должны иметь возможность открывать "screen.dib" в большинстве средств просмотра / редактирования фотографий (например, GIMP или другие)

byte[] rawImg = array;

File.WriteAllBytes("screen.dib", rawImg);
Другие вопросы по тегам