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

发布于 2024-07-15 11:15:57 字数 1251 浏览 7 评论 0原文

我正在从智能相机成像器捕获图像,并通过套接字编程从相机接收字节数组(.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 中不起作用。

谁能帮我 ?

PS:

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

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

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

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).

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

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.

Can anyone help me ?

P.S :

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

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

None of the above methods worked. Kindly help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

意中人 2024-07-22 11:15:57

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

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

Image.FromStream(new MemoryStream(myImageByteArray));

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

我也经历过惨痛的教训才知道这一点。

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

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 MemoryStream with that:

Image.FromStream(new MemoryStream(myImageByteArray));

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

I've learned that the hard way, too.

往日情怀 2024-07-22 11:15:57

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

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

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

byteBlobData = (Byte[]) reader.GetValue(0);
stream = new MemoryStream(byteBlobData, 88, byteBlobData.Length - 88);
img = Image.FromStream(stream);
唱一曲作罢 2024-07-22 11:15:57

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

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

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


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

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 sure it's the exact same byte array you're feeding the C++ application?

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.FromStream understands). The Bitmap(Int32, Int32, Int32, PixelFormat, IntPtr) constructor may be of use here. Or, you can create the blank bitmap and blt it manually from the raw data.

吹梦到西洲 2024-07-22 11:15:57

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

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

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();
影子是时光的心 2024-07-22 11:15:57

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

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

流年里的时光 2024-07-22 11:15:57

试试这个:

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

希望有帮助!

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!

优雅的叶子 2024-07-22 11:15:57

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

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.

爱已欠费 2024-07-22 11:15:57

此代码正在运行

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

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();
梦醒灬来后我 2024-07-22 11:15:57

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

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

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

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;
}
眼中杀气 2024-07-22 11:15:57

从数据库加载后,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();

After load from DataBase byteArray has more byte than one image. In my case it was 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)

        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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文