2012-01-13 188 views
3

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

存储过程

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

任何想法都会有所帮助。

+0

http://stackoverflow.com/a/6712677/284240二进制数据保存到文件中,看到的图像编辑器如何响应其 – 2012-01-13 15:57:51

回答

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 
} 
+1

他需要确保流保持打开状态,直到完成Image。 – insipid 2012-01-13 16:09:26

+0

好的,我会试试看看它是否有效。 – 2012-01-13 16:20:29

+0

在尝试从内存流中绘制图像之前,我修改了一些流指向开头的代码,但它仍然引发相同的错误。 – 2012-01-16 11:05:47

0

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

2

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

+0

你会如何建议我改变我的代码,因为我没有想法? – 2012-01-16 11:15:20

+0

你根本不应该序列化,这是没有意义的。如果参数来自数据集,它应该已经是一个byte类型的数组。 – insipid 2012-01-18 01:22:22

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