Image.FromStream()方法返回Invalid Argument异常

时间:2009-03-24 03:28:06

标签: c# .net image exception memorystream

我从智能相机成像仪捕获图像并通过套接字编程从相机接收字节数组(.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;
}

我在许多论坛中搜索过这个问题并尝试过许多专家提出的建议,但没有任何帮助。

我不认为字节数组有任何问题,因为当我将相同的字节数组输入我的VC ++ 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;
}

以上方法均无效。请帮助。

10 个答案:

答案 0 :(得分:7)

Image.FromStream()期望一个只包含一张图片的流!

它将stream.Position重置为0.我有一个包含多个图像或其他内容的流,您必须将图像数据读入字节数组并初始化 MemoryStream 那个:

Image.FromStream(new MemoryStream(myImageByteArray));

只要图像正在使用, MemoryStream 就必须保持打开状态。

我也很努力地说。 :)

答案 1 :(得分:4)

可能图像嵌入在OLE字段中,您必须考虑88字节的OLE标头加上有效负载:

byteBlobData = (Byte[]) reader.GetValue(0);
stream = new MemoryStream(byteBlobData, 88, byteBlobData.Length - 88);
img = Image.FromStream(stream);

答案 2 :(得分:3)

我猜测从服务器接收文件时出现了问题。在尝试将其转换为Image之前,您可能只获得了部分文件?你确定它是你为C ++应用程序提供的完全相同的字节数组吗?

尝试将流保存到文件中,看看你得到了什么。你或许可以在那里发现一些线索。

您还可以添加断点并手动将字节数组中的某些字节与它们应该的字节进行比较(如果您知道的话)。


编辑:看起来接收数据没有任何问题。问题是它是原始格式(不是Image.FromStream理解的格式)。 Bitmap(Int32, Int32, Int32, PixelFormat, IntPtr) constructor可能在这里有用。或者,您可以创建空白位图并从原始数据手动blt。

答案 3 :(得分:3)

我这样做时遇到了这个问题:

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();

答案 4 :(得分:1)

System.InvalidArgument表示流没有有效的图像格式,即不支持的图像类型。

答案 5 :(得分:1)

试试这个:

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

希望它有所帮助!

答案 6 :(得分:0)

我过去遇到了同样的问题,它是由Windows GDI库中的泄漏引起的,这就是'Bitmap'使用的。如果这种情况一直发生在你身上,那么它可能是无关的。

答案 7 :(得分:0)

此代码正常运作

        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();

答案 8 :(得分:0)

尝试使用类似于此处所述的内容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;
}

答案 9 :(得分:0)

从数据库中加载后,byteArray的字节数大于一个图像。在我的情况下,是82。

MemoryStream ms = new MemoryStream();
ms.Write(byteArray, 82, byteArray.Length - 82);
Image image = Image.FromStream(ms);

为了保存在数据库中,我插入82字节以开始流。 Properties.Resources.ImgForDB-它是包含那些82字节的二进制文件。 (我的下一个路径是-将图像从数据库加载到MemoryStream并先保存到82个字节的二进制文件中。您可以在此处使用它-https://yadi.sk/d/bFVQk_tdEXUd-A

        MemoryStream temp = new MemoryStream();
        MemoryStream ms = new MemoryStream();
        OleDbCommand cmd;
        if (path != "")
        {
            Image.FromFile(path).Save(temp, System.Drawing.Imaging.ImageFormat.Bmp);
            ms.Write(Properties.Resources.ImgForDB, 0, Properties.Resources.ImgForDB.Length);
            ms.Write(temp.ToArray(), 0, temp.ToArray().Length);

        cmd = new OleDbCommand("insert into Someone (first, Second, Third) values (@a,@b,@c)", connP);
        cmd.Parameters.AddWithValue("@a", fio);
        cmd.Parameters.AddWithValue("@b", post);
        cmd.Parameters.AddWithValue("@c", ms.ToArray());
        cmd.ExecuteNonQuery();