Метод Image.FromStream () возвращает исключение Invalid Argument - PullRequest
10 голосов
/ 24 марта 2009

Я снимаю изображения со смарт-камеры и получаю массив байтов с камеры через программирование сокетов (.NET-приложение - это клиент, камера - это сервер).

Проблема в том, что я получаю исключение System.InvalidArgument во время выполнения.

private Image byteArrayToImage(byte[] byteArray) 
{
    if(byteArray != null) 
    {
        MemoryStream ms = new MemoryStream(byteArray);
        return Image.FromStream(ms, false, false); 
        /*last argument is supposed to turn Image data validation off*/
    }
    return null;
}

Я искал эту проблему на многих форумах и пробовал предложения многих экспертов, но ничего не помогло.

Я не думаю, что есть какая-то проблема с байтовым массивом как таковым, потому что, когда я передаю тот же байтовый массив в мое клиентское приложение VFC ++ MFC, я получаю изображение. Но это как-то не работает в C # .NET.

Кто-нибудь может мне помочь?

P.S .:

Другие методы, которые я пытался выполнить для этой же задачи:

1

private Image byteArrayToImage(byte[] byteArray)
{
    if(byteArray != null) 
    {
        MemoryStream ms = new MemoryStream();
        ms.Write(byteArray, 0, byteArray.Length);
        ms.Position = 0; 
        return Image.FromStream(ms, false, false);
    }
    return null;
}

2

private Image byteArrayToImage(byte[] byteArray) 
{
    if(byteArray != null) 
    {
        TypeConverter tc = TypeDescriptor.GetConverter(typeof(Bitmap));
        Bitmap b = (Bitmap)tc.ConvertFrom(byteArray);
        return b;
    }
    return null;
}

Ни один из вышеперечисленных методов не работал. Пожалуйста, помогите.

Ответы [ 9 ]

7 голосов
/ 09 октября 2013

Image.FromStream() ожидает поток, содержащий ТОЛЬКО одно изображение!

Сбрасывает поток. Положите на 0. Если у вас есть поток, содержащий несколько изображений или другой материал, вы должны прочитать данные изображения в байтовый массив и инициализировать MemoryStream что:

Image.FromStream(new MemoryStream(myImageByteArray));

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

Я тоже усердно учил это. :)

4 голосов
/ 02 февраля 2010

Может быть, изображение встроено в поле OLE, и вам необходимо учитывать 88-байтовый заголовок OLE плюс полезную нагрузку:

byteBlobData = (Byte[]) reader.GetValue(0);
stream = new MemoryStream(byteBlobData, 88, byteBlobData.Length - 88);
img = Image.FromStream(stream);
3 голосов
/ 28 октября 2009

У меня была эта проблема при этом:

MemoryStream stream = new MemoryStream();
screenshot.Save(stream, ImageFormat.Png);
byte[] bytes = new byte[stream.Length];
stream.Save(bytes, 0, steam.Length);

С последними двумя строками. Я исправил это следующим образом:

MemoryStream stream = new MemoryStream();
screenshot.Save(stream, ImageFormat.Png);
byte[] bytes = stream.ToArray();

И тогда это сработало:

MemoryStream stream = new MemoryStream(bytes);
var newImage = System.Drawing.Image.FromStream(stream);
stream.Dispose();
3 голосов
/ 24 марта 2009

Я предполагаю, что что-то идет не так при получении файла с сервера. Возможно, вы получаете только часть файла, прежде чем пытаться преобразовать его в Image? Вы уверены это тот же байтовый массив, который вы используете для приложения C ++?

Попробуйте сохранить поток в файл и посмотреть, что вы получите. Вы могли бы найти некоторые подсказки там.

Вы также можете добавить точку останова и вручную сравнить некоторые байты в массиве байтов с тем, что они должны быть (если вы это знаете).


Редактировать: Похоже, нет ничего плохого в получении данных. Проблема в том, что он в необработанном формате (а не в формате, понятном Image.FromStream). Bitmap(Int32, Int32, Int32, PixelFormat, IntPtr) конструктор может быть полезен здесь. Или вы можете создать пустое растровое изображение и вручную скопировать его из необработанных данных.

1 голос
/ 05 мая 2017

Попробуйте это:

public Image byteArrayToImage(byte[] item)
{          
   Image img=Image.FromStream(new MemoryStream(item)); 
   img.Save(Response.OutputStream, ImageFormat.Gif);
   return img;
}

Надеюсь, это поможет!

1 голос
/ 24 марта 2009

System.InvalidArgument означает, что поток не имеет допустимого формата изображения, то есть тип изображения, который не поддерживается.

0 голосов
/ 05 января 2018

Попробуйте использовать что-то похожее на то, что описано здесь https://social.msdn.microsoft.com/Forums/vstudio/en-US/de9ee1c9-16d3-4422-a99f-e863041e4c1d/reading-raw-rgba-data-into-a-bitmap

Image ImageFromRawBgraArray(
    byte[] arr, 
    int charWidth, int charHeight,
    int widthInChars, 
    PixelFormat pixelFormat)
{
    var output = new Bitmap(width, height, pixelFormat);
    var rect = new Rectangle(0, 0, width, height);
    var bmpData = output.LockBits(rect, ImageLockMode.ReadWrite, output.PixelFormat);

    // Row-by-row copy
    var arrRowLength = width * Image.GetPixelFormatSize(output.PixelFormat) / 8;
    var ptr = bmpData.Scan0;
    for (var i = 0; i < height; i++)
    {
        Marshal.Copy(arr, i * arrRowLength, ptr, arrRowLength);
        ptr += bmpData.Stride;
    }

    output.UnlockBits(bmpData);
    return output;
}
0 голосов
/ 07 декабря 2015

этот код работает

        string query="SELECT * from gym_member where Registration_No ='" + textBox9.Text + "'";

        command = new SqlCommand(query,con);
        ad = new SqlDataAdapter(command);
        DataTable dt = new DataTable();
        ad.Fill(dt);
        textBox1.Text = dt.Rows[0][1].ToString();
        textBox2.Text = dt.Rows[0][2].ToString();
        byte[] img = (byte[])dt.Rows[0][18];
        MemoryStream ms = new MemoryStream(img);

        pictureBox1.Image = Image.FromStream(ms);
        ms.Dispose();
0 голосов
/ 24 марта 2009

В прошлом у меня была такая же проблема, и она была вызвана утечкой в ​​библиотеках Windows GDI, которую использует «Bitmap». Если это происходит для вас все время, то, вероятно, это не связано.

...