2012-06-01 73 views
8

Estoy intentando guardar y cargar imágenes con SQLite con una aplicación en WinForm con CF. Encontré una manera de guardar una imagen en el archivo db, pero no sé si es correcto porque no pude encontrar la manera de cargar la imagen almacenada en el db.Guardar y cargar imagen SQLite C#

que tienen un código para convertir mi imagen en una base 64:

public void ImageToBase64(Image image, System.Drawing.Imaging.ImageFormat format){ 
     using (MemoryStream ms = new MemoryStream()){ 
      // Convert Image to byte[] 
      image.Save(ms, format); 
      byte[] imageBytes = ms.ToArray(); 

      // Convert byte[] to Base64 String 
      string base64String = Convert.ToBase64String(imageBytes); 
      SaveImage(base64String); 
     } 
    } 

Este es mi código para guardar la imagen en el PP:

void SaveImage(string pic){ 
     string query = "insert into Table (Photo) values (@pic);"; 
     string conString = @" Data Source = \Program Files\Users.s3db ";    
     SQLiteConnection con = new SQLiteConnection(conString); 
     SQLiteCommand cmd = new SQLiteCommand(query, con); 
     cmd.Parameters.Add("@pic",DbType.String); 
     con.Open(); 
     try{ 
      cmd.ExecuteNonQuery(); 
     } 
     catch (Exception exc1){ 
      MessageBox.Show(exc1.Message); 
     } 
     con.Close(); 
    } 

Tengo un código para hacer lo contrario de ImageToBase64 pero primero necesito cargar la imagen desde el db. Alguna idea de hacer eso?

EDIT Estoy tratando de usar la burbuja para guardar la imagen ahora como Charlie sugirió. Probé este código:

Image photo = new Bitmap(@"\Photos\Image20120601_1.jpeg"); 
SaveImage(photo); 

void SaveImage(Image pic){ 
string conString = @" Data Source = \Program Files\Users.s3db ";    
SQLiteConnection con = new SQLiteConnection(conString); 
SQLiteCommand cmd = con.CreateCommand(); 
cmd.CommandText = String.Format("INSERT INTO Table (Photo) VALUES (@0);"); 
SQLiteParameter param = new SQLiteParameter("@0", System.Data.DbType.Binary); 
param.Value = pic; 
cmd.Parameters.Add(param); 
con.Open(); 
try{ 
    cmd.ExecuteNonQuery(); 
} 
catch (Exception exc1){ 
    MessageBox.Show(exc1.Message); 
} 
con.Close();} 

Pero cuando ExcecuteNonQuery() que coger un error de InvalidCastException.

¿Alguna sugerencia?

SOLUCIÓN Este código guardar una imagen en la base de datos y luego cargar la imagen a mostrar en un cuadro de imagen:

namespace ImagenSQLite 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
      Image photo = new Bitmap(@"\Photos\Image20120601_1.jpeg"); 
      byte[] pic = ImageToByte(photo, System.Drawing.Imaging.ImageFormat.Jpeg); 
      SaveImage(pic); 
      LoadImage(); 
     } 

     public byte[] ImageToByte(Image image, System.Drawing.Imaging.ImageFormat format){ 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       // Convert Image to byte[] 
       image.Save(ms, format); 
       byte[] imageBytes = ms.ToArray(); 
       return imageBytes; 
      } 
     } 
     //public Image Base64ToImage(string base64String) 
     public Image ByteToImage(byte[] imageBytes) 
     { 
      // Convert byte[] to Image 
      MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length); 
      ms.Write(imageBytes, 0, imageBytes.Length); 
      Image image = new Bitmap(ms); 
      return image; 
     } 
     /***************** SQLite **************************/ 
     void SaveImage(byte[] imagen){ 
      string conStringDatosUsuarios = @" Data Source = \Program Files\GPS___CAM\Data\DatosUsuarios.s3db ";    
      SQLiteConnection con = new SQLiteConnection(conStringDatosUsuarios); 
      SQLiteCommand cmd = con.CreateCommand(); 
      cmd.CommandText = String.Format("INSERT INTO Empleados (Foto) VALUES (@0);"); 
      SQLiteParameter param = new SQLiteParameter("@0", System.Data.DbType.Binary); 
      param.Value = imagen; 
      cmd.Parameters.Add(param); 
      con.Open(); 

      try 
      { 
       cmd.ExecuteNonQuery(); 
      } 
      catch (Exception exc1) 
      { 
       MessageBox.Show(exc1.Message); 
      } 
      con.Close(); 
     } 
     void LoadImage(){ 
      string query = "SELECT Photo FROM Table WHERE ID='5';"; 
      string conString = @" Data Source = \Program Files\Users.s3db "; 
      SQLiteConnection con = new SQLiteConnection(conString); 
      SQLiteCommand cmd = new SQLiteCommand(query, con);    
      con.Open(); 
      try 
      { 
       IDataReader rdr = cmd.ExecuteReader(); 
       try 
       { 
        while (rdr.Read()) 
        { 
         byte[] a = (System.Byte[])rdr[0]; 
         pictureBox1.Image = ByteToImage(a); 
        } 
       } 
       catch (Exception exc) { MessageBox.Show(exc.Message); } 
      } 
      catch (Exception ex) { MessageBox.Show(ex.Message); } 
      con.Close(); 
     }  
    } 
} 

Gracias por su ayuda!

Respuesta

4

Para cargar la imagen de la base de datos, utiliza una instrucción SQL select para recuperar los datos, tal como lo haría con cualquier otro tipo de datos. La imagen codificada en base64 se almacena como una cadena en la base de datos SQLite. Por lo tanto, lo recuperará como una cadena, como si estuviera almacenando cualquier otra cadena (como, por ejemplo, su nombre) en la base de datos.

string LoadImage() { 
    string query = "select Photo from Table;"; 
    string conString = @" Data Source = \Program Files\Users.s3db ";    
    SQLiteConnection con = new SQLiteConnection(conString); 
    SQLiteCommand cmd = new SQLiteCommand(query, con); 
    string base64EncodedImage = null; 
    con.Open(); 
    try { 
     IDataReader reader = cmd.ExecuteReader(); 
     reader.Read(); // advance the data reader to the first row 
     base64EncodedImage = (string) reader["Photo"]; 
     reader.Close(); 
    } 
    catch (Exception ex) { 
     MessageBox.Show(ex.Message); 
    } 
    con.Close(); 
    return base64EncodedImage; 
} 

Al igual que su código de guardado, mi código de ejemplo para cargar la imagen utiliza solo una imagen guardada en la tabla. Para cargar y guardar más de una imagen, deberá insertar un campo de ID en la tabla y luego usar una cláusula where en su declaración SQL select.


No estoy seguro de que yo, personalmente, almaceno la imagen como una cadena codificada en base64. La representación de cadena de la imagen será mucho más grande que la representación binaria. SQLite supports the BLOB data type, entonces buscaría usar eso.

+0

Charlie, gracias por su respuesta. Probé tu código, pero en la línea donde insertas el lector en una cadena, detecta un error de CastInvalidException. Esta es mi línea 'base64EncodedImage = (string) reader [" Photo "];'. Tal vez no estoy guardando con éxito la imagen, ¿podría ser? –

+0

Tal vez el problema es que el campo Foto es blob, ¿podría ser eso? –

+0

Si no guardo la imagen como base64, ¿debería pasar la imagen directamente a la base de datos? Debo poner 'GuardarImagen (Imagen Foto) 'y'cmd.Parameters.Add (' @ pic ', DbType.Binary);'? –