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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/676072/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 13:00:16  来源:igfitidea点击:

Image.FromStream() method returns Invalid Argument exception

c#.netimageexceptionmemorystream

提问by

I am capturing images from a smart camera imager and receiving the byte array from the camera through socket programming (.NET application is the client, camera is the server).

我正在从智能相机成像器捕获图像并通过套接字编程从相机接收字节数组(.NET 应用程序是客户端,相机是服务器)。

The problem is that i get System.InvalidArgument exception at runtime.

问题是我在运行时收到 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;
}

I have searched this problem in many forums and tried the suggestions given by many experts but nothing helped.

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

I dont think there is any problem with the byte array as such because When i feed the same byte array into my VC++ MFC client application, i get the image. But this doesn't somehow work in C#.NET.

我不认为字节数组有任何问题,因为当我将相同的字节数组提供给我的 VC++ MFC 客户端应用程序时,我得到了图像。但这在 C#.NET 中不起作用。

Can anyone help me ?

谁能帮我 ?

P.S :

附注:

Other methods i've tried to accomplish the same task are:

我尝试完成相同任务的其他方法是:

1.

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.

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;
}

None of the above methods worked. Kindly help.

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

回答by Mitch Wheat

System.InvalidArgumentmeans The stream does not have a valid image format, i.e. an image type that is not supported.

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

回答by Chris

I've had the same problem in the past and it was caused by a leak within the windows GDI libraries, which is what 'Bitmap' uses. If this happening all the time for you then its probably unrelated, however.

我过去遇到过同样的问题,它是由 windows GDI 库中的泄漏引起的,这就是“位图”使用的。但是,如果这种情况一直发生在您身上,那么它可能无关紧要。

回答by lc.

I'm guessing that something is going wrong when receiving the file from the server. Perhaps you're only getting part of the file before trying to convert it to an Image? Are you sureit's the exact same byte array you're feeding the C++ application?

我猜测从服务器接收文件时出现问题。也许在尝试将文件转换为Image? 您确定它与您提供给 C++ 应用程序的字节数组完全相同吗?

Try saving the stream to a file and see what you get. You might be able to uncover some clues there.

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

You can also add a breakpoint and manually compare some of the bytes in the byte array to what they're supposed to be (if you know that).

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



Edit: It looks like there's nothing wrong with receiving the data. The problem is that it's in raw format (not a format that Image.FromStreamunderstands). The Bitmap(Int32, Int32, Int32, PixelFormat, IntPtr)constructormay be of use here. Or, you can create the blank bitmap and blt it manually from the raw data.

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

回答by NotDan

I've had this problem when doing this:

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

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

With the last 2 lines being the problem. I fixed it by doing this:

最后两行是问题所在。我通过这样做修复了它:

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

And then this worked:

然后这有效:

MemoryStream stream = new MemoryStream(bytes);
var newImage = System.Drawing.Image.FromStream(stream);
stream.Dispose();

回答by Jose Martin

Maybe the image is embedded in an OLE field and you have to consider the 88 bytes OLE header plus payload:

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

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

回答by supernorbert

Image.FromStream()expects a stream that contains ONLY one image!

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

It resets the stream.Position to 0. I've you have a stream that contains multiple images or other stuff, you have to read your image data into a byte array and to initialize a MemoryStreamwith that:

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

Image.FromStream(new MemoryStream(myImageByteArray));

The MemoryStreamhas to remain open as long as the image is in use.

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

I've learned that the hard way, too.

我也学到了这一点。

回答by Mohd Aamir Ansari

this code is working

此代码正在工作

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

回答by Sathiyamoorthi S

Try this:

尝试这个:

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

Hope it helps!

希望能帮助到你!

回答by Andrey Belykh

Try to use something similar to what is described here https://social.msdn.microsoft.com/Forums/vstudio/en-US/de9ee1c9-16d3-4422-a99f-e863041e4c1d/reading-raw-rgba-data-into-a-bitmap

尝试使用类似于此处描述的内容https://social.msdn.microsoft.com/Forums/vstudio/en-US/de9ee1c9-16d3-4422-a99f-e863041e4c1d/reading-raw-rgba-data-into-位图

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;
}

回答by Василий

After load from DataBase byteArray has more byte than one image.In my case it was 82.

从数据库加载后,byteArray 的字节数多于一张图像。就我而言,它是 82。

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

And for save in the DB I insert 82 byte to begin stream. Properties.Resources.ImgForDB- it is binary file that contain those 82 byte. (I get it next path - Load Image from DB to MemoryStream and save to binary file first 82 byte. You can take it here - https://yadi.sk/d/bFVQk_tdEXUd-A)

为了保存在数据库中,我插入 82 字节开始流。Properties.Resources.ImgForDB- 它是包含那些 82 字节的二进制文件。(我得到了下一条路径 - 从 DB 加载图像到 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();