将字节数组转换为图像:参数无效

时间:2012-01-13 15:50:16

标签: c# asp.net image bytearray filestream

我将图像存储在数据库中,并希望将它们从字节数组转换为图像。我没有问题将对象转换为字节数组但是在尝试从字节数组转换为图像时出现“参数无效”错误。我传递给我的方法的对象来自数据集行。

存储过程

USE [----------------]
GO
/****** Object:  StoredProcedure [dbo].[usp_imageloader_add_test]    Script Date: 01/16/2012    09:19:46 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER   procedure [dbo].[usp_imageloader_add_test]
@p_Image Image

as 

INSERT into Test_Images VALUES(@p_Image)

上传文件控件 /将图像文件转换为字节数组并将数据保存到数据库

 protected void btnUpload_Click(object sender, EventArgs e)
    {
        if (ctrlUpload.PostedFile != null)
        {
            if (ctrlUpload.PostedFile.ContentLength > 0)
            {
                // Get Posted File
                HttpPostedFile objHttpPostedFile = ctrlUpload.PostedFile;

                // Find its length and convert it to byte array
                int ContentLength = objHttpPostedFile.ContentLength;

                // Create Byte Array
                byte[] bytImg = new byte[ContentLength];

                // Read Uploaded file in Byte Array
                objHttpPostedFile.InputStream.Read(bytImg, 0, ContentLength);

                using (SqlConnection dbConnection = new SqlConnection(app_settings.sql_conn_string_db))
                {
                    try
                    {
                        string sql = "usp_imageloader_add_test";
                        SqlCommand cmd = new SqlCommand(sql, dbConnection);
                        cmd.CommandType = System.Data.CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@p_Image", bytImg).SqlDbType = SqlDbType.Image;
                        cmd.Connection.Open();
                        cmd.ExecuteNonQuery();
                        cmd.Connection.Close();
                    }


                    catch (Exception ex)
                    {
                        ex.Message.ToString();
                    }
                }
            }
        }
    }

将对象转换为字节数组并转换为图像

 private System.Drawing.Image ObjToImg(object obj)
    {
        byte[] byteArray;
        if (obj == null)
            return null;
        else
        {
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            bf.Serialize(ms, obj);
            byteArray = ms.ToArray(); // Byte Array
            ms.Close();

            ms = new MemoryStream(byteArray, 0, byteArray.Length);
            ms.Seek(0, SeekOrigin.Begin);
            System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms);
            return returnImage;
        }

任何想法都会有所帮助。

5 个答案:

答案 0 :(得分:2)

Image.FromStream可能会抛出ArgumentException,因为图片格式无效。期望将随机序列化对象格式化为有效图像是不合理的。

答案 1 :(得分:1)

尝试以下操作,您的信息流可能不会初始化为开头:

ms = new MemoryStream(byteArray, 0, byteArray.Length);
ms.Seek(0, SeekOrigin.Begin);
System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms);

它是什么类型的图像?您确定存储的图像是否有效?

此外,只是对使用情况的评论(不会影响您的问题),在使用流时,最好使用using语句。例如:

using (MemoryStream ms = new MemoryStream())
{
    // your code here
}

答案 2 :(得分:1)

您使用的是原始RGB数据吗?如果是这样,那么在FromStream()的文档中有一个用户注释,它提到如果流包含原始RGB数据,该方法将抛出:http://msdn.microsoft.com/en-us/library/93z9ee4x.aspx(参见页面底部);它建议改为使用位图(http://msdn.microsoft.com/en-us/library/zy1a2d14.aspx)。

答案 3 :(得分:0)

Kelsey的解决方案应该有效。这是因为,当您从byteArray读取数据到内存流时,指针放在流的末尾,现在当您尝试从此内存流中读取数据时,它会尝试读取此指针的头部,并在那里在此之后没有数据,你得到一个错误。现在,如果执行ms.Seek(0, SeekOrigin.Begin);,则读取器指针位于内存流的开头。完成后使用ms.Dispose()处理内存流。希望这会有所帮助。

答案 4 :(得分:0)

你不需要二进制格式化程序,这就是弄乱你的数据,而是真正用于序列化对象。

需要注意的关键是该对象已经是一个字节数组,因此您可以将其强制转换并使用它。

试试这个: -

    private System.Drawing.Image ObjToImg(object obj)
    {
        if (obj == null)
            return null;
        else
        {
            byte[] byteArray = (byte[])obj;
            System.Drawing.Image returnImage;
            using (var ms = new MemoryStream(byteArray, 0, byteArray.Length))
            {
                returnImage = System.Drawing.Image.FromStream(ms);
            }
            return returnImage;
        }
    }