2012-01-16 31 views
7

Estoy almacenando imágenes en una base de datos y me gustaría convertirlas de una matriz de bytes a una imagen. No tengo problemas para convertir un objeto en matriz de bytes, pero aparece el error "El parámetro no es válido" cuando intento convertir de una matriz de bytes a una imagen. El objeto que paso a mi método proviene de una fila de conjunto de datos.Guardar un archivo de imagen en el servidor sql y convertir una matriz de bytes en la imagen

Procedimiento almacenado

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) 

control de carga de archivos/convertir archivos de imagen de matriz de bytes y guardar los datos en la base de datos

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.Binary; 
         cmd.Connection.Open(); 
         cmd.ExecuteNonQuery(); 
         cmd.Connection.Close(); 
        } 


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

método de la tabla, que llama al método objToImg

protected void Page_Load(object sender, EventArgs e) 
    { 
     generateTable(false); 
    } 


private Table generateTable(bool flag) 
    { 
     Table tb = BuildList(GetData(), flag); 
     if (imgloadercms != null) 
     { 

      PlaceHolder ph = new PlaceHolder(); 
      StringBuilder sb = new StringBuilder(); 
      ph.Controls.Add(new LiteralControl(sb.ToString())); 
     } 
     imgloadercms.Controls.Add(tb); 
     return tb; 
    } 


protected Table BuildList(DataTable tb, bool flag) 
    { 
     Table tblImageLibrary = new Table(); 
     tblImageLibrary.BorderStyle = BorderStyle.Solid; 
     tblImageLibrary.BorderWidth = Unit.Pixel(8); 

     if (tb.Rows.Count > 0) 
     { 
      try 
      { 
       if (!flag) 
       { 

        tblImageLibrary.BorderColor = Color.Black; 
        tblImageLibrary.BorderWidth = Unit.Pixel(1); 
        TableRow tr = new TableRow(); // Table row for header of table 
        tr.BackColor = Color.LightBlue; 

        TableCell c1 = new TableCell(); 
        TableCell c2 = new TableCell(); 


        c1.Controls.Add(new LiteralControl("Image Id")); 
        tr.Cells.Add(c1); 
        c2.Controls.Add(new LiteralControl("Image")); 
        tr.Cells.Add(c2); 

        tblImageLibrary.Rows.Add(tr); 
       } 

       int i = 0; 

       foreach (DataRow r in tb.Rows) // Create new row foreach row in table 
       { 
        TableRow tr = new TableRow(); 
        if (i % 2 == 0) 
        { 
         tr.BackColor = Color.LightYellow; 
        } 
        // Build cells 
        TableCell c1 = new TableCell(); 
        TableCell c2 = new TableCell(); 
        c2.Width = 300; 

        c1.Controls.Add(new LiteralControl(r["Image_Id"].ToString())); 
        tr.Cells.Add(c1); 

        // Call method to serialize obj to byte array 
        //System.Drawing.Image dbImg = 
        ObjToImg(r["Image_File"]); 

       } 
      catch (Exception ex) 
      { 
       ex.ToString(); 
      } 
      if (!flag) 
      { 

      } 
     } 
     return tblImageLibrary; 
    } 

Image regresar

private System.Drawing.Image ObjToImg(object obj) 
    { 
     //byte[] byteArray = null; 

     if (obj == null) 
      return null; 
     else 
     { 

      BinaryFormatter bf = new BinaryFormatter(); 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       bf.Serialize(ms, obj); //now in Memory Stream 
       ms.ToArray(); // Array object 
       ms.Seek(0, SeekOrigin.Begin); 

       //return (System.Drawing.Image)bf.Deserialize(ms); 

       System.Drawing.Image myImage = (System.Drawing.Image)bf.Deserialize(ms); 

       return myImage; 
      } 

Siempre que trato de agregar el objeto de secuencia de memoria para el constructor de objetos de imagen me sale el mensaje de error de "parámetro no es válido". Tal vez cometí un error al insertar la matriz de bytes en la base de datos porque he examinado otro código y no tiene sentido cómo no funciona.

+0

Muéstranos también dónde pasa los bytes a 'ObjToImg' –

+0

Tenía un código similar, en el que utilicé' varbinary (max) 'en lugar de' image'. EDIT: acaba de encontrar este enlace también - http://stackoverflow.com/questions/4113294/is-there-a-big-technical-difference-between-varbinarymax-and-image-data-types – robasta

+0

Es de una fila en una tabla de datos. Actualizaré mi publicación original. –

Respuesta

1

Probar deserializar el objeto primero de la matriz de bytes con su BinaryFormatter!

Trate de usar dos métodos siguientes:

private System.Drawing.Image ObjToImg(byte[] obj) 
    { 
     if (obj == null) 
      return null; 
     else 
     { 
      BinaryFormatter bf = new BinaryFormatter(); 
      using(MemoryStream ms = new MemoryStream(obj)) 
      { 
       return (System.Drawing.Image)bf.Deserialize(ms); 
      } 
     } 
    } 
private byte[] ImgToObj(System.Drawing.Image obj) 
    { 
     if (obj == null) 
      return null; 
     else 
     { 
      BinaryFormatter bf = new BinaryFormatter(); 
      using(MemoryStream ms = new MemoryStream()) 
      { 
       bf.Serialize(ms, obj); 
       return ms.ToArray(); 
      } 
     } 
    } 
+0

El SqlDbType se estableció originalmente en Image, pero yo no hice la diferencia. –

+0

Lo intenté y arrojó una excepción de "intentar deserializar una secuencia vacía". –

+0

Definitivamente se produce un problema con la operación con la salida de su formateador - compruébelo. –

1

hace poco que tenía que hacer exactamente lo mismo en VB.NET. Aquí está mi código, ejecuta el convertidor de código de Telerik. Fue bastante complicado trabajar, y sigue siendo un verdadero dolor.

Para cargar una imagen:

private bool uploadImage(ref Bitmap p) 
{ 
    SqlConnection con = new SqlConnection(); 
    con.ConnectionString = Configuration.ConfigurationManager.ConnectionStrings("ConnStringHere").ConnectionString; 
    SqlCommand cmd = new SqlCommand(); 
    cmd.CommandText = "INSERT INTO Table_Name (File2) VALUES (@File2)"; //I named the column File2 simply because "File" seemed to be a keyword in SQLServer 
    cmd.CommandType = CommandType.Text; 
    cmd.Connection = con; 

    SqlParameter File1 = new SqlParameter("@File2", SqlDbType.Image); 
    MemoryStream ms = new MemoryStream(); 

    using (Bitmap tempImage = new Bitmap(p)) 
    { 
     tempImage.Save(ms, p.RawFormat); 
    } 

    byte[] data = ms.GetBuffer(); 
    if (!isValidImage(data)) //optional, will include code if requested. 
    { 
     return false; 
    } 
    File1.Value = data; 
    cmd.Parameters.Add(File1); 

    con.Open(); 
    int result = cmd.ExecuteNonQuery(); 
    if (result > 0) 
    { 
     // SUCCESS! 
     con.Close(); 
     return true; 
    } 
    else 
    { 
     //failure 
     con.Close(); 
     return false; 
    } 

} 

Para recuperar una imagen:

private Bitmap retrieveBitmap() 
    { 
     Image image1 = null 
     if (dt1.Rows.Count > 0) 
     { 
      byte[] imageData1 = null; 
      if (dt1[0].Count > 0) 
      { 
       if (!Information.IsDBNull(dt1.CopyToDataTable()[0].Item("File2"))) 
       { 
        imageData1 = (byte[])dt1.CopyToDataTable()[0].Item("File2"); 
       } 
      } 
      if ((imageData1 != null)) 
      { 
       if (isValidImage(imageData1)) 
       { 
        using (MemoryStream ms = new MemoryStream(imageData1, 0, imageData1.Length)) 
        { 
         ms.Write(imageData1, 0, imageData1.Length); 
         image1 = Image.FromStream(ms, true); 
        } 
        return image1; 
       } 
       else 
       { 
        // "Invalid image on server"; 
        return null; 
       } 
      } 
     } 
    } 

Mi código puede necesitar pequeños cambios de formato, por favor editar todo lo que tiene sintaxis no válida (mi C# es un poco oxidado, y mi código se ejecutó a través de un convertidor).

Cuestiones relacionadas