【问题标题】:Convert Byte Array to Image: Parameter is not valid将字节数组转换为图像:参数无效
【发布时间】:2012-02-09 19:33:18
【问题描述】:

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

存储过程

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

任何想法都会有所帮助。

【问题讨论】:

标签: c# asp.net image bytearray filestream


【解决方案1】:

你不需要二进制格式化程序,那是你的数据搞砸了,它真的是为了序列化对象。

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

试试这个:-

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 由于我没有想法,您会如何建议我更改代码?
    • 你根本不应该序列化,这没有任何意义。如果参数来自数据集,它应该已经是一个字节类型的数组。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      尝试以下操作,您的流可能没有初始化到开头:

      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
      }
      

      【讨论】:

      • 他需要确保流保持打开状态,直到他处理完图像。
      • 在尝试从内存流中绘制图像之前,我修改了一些流指向开头的代码,但仍然抛出相同的错误。
      • @nick gowdy 这是什么类型的图像?您是否验证了存储的图像是有效的?
      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-05-18
        • 2013-07-14
        • 1970-01-01
        • 2015-08-16
        • 2013-05-19
        相关资源
        最近更新 更多