2012-01-13 134 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; 
     } 
    }