Guardar Imagen en base de datos. (c#)

Iniciado por Hartigan, 13 Junio 2010, 20:25 PM

0 Miembros y 6 Visitantes están viendo este tema.

43H4FH44H45H4CH49H56H45H

Cita de: Hartigan en 15 Junio 2010, 13:48 PM
Bueno no hay manera. He seguido tropecientos tutoriales y esque hay algo que no va bien. En la parte en la que se hace la conversión de bytes al tipo image, toma el valor null, no se porqué y entonces no le asigna nada... Creo que voy a desistir y a probar el método de almacenar solo la dirección local de la imágen.

Puedes leer que almaceno en la BD sin asignar la imagen al picturebox.
Si leemos algunos bytes antes de almacenarlos:

Código (csharp) [Seleccionar]
System.IO.Stream derecho = new System.IO.MemoryStream();
this.pictureBox1.Image.Save(derecho, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] imgDerecha = new byte[derecho.Length];
derecho.Position = 0;
derecho.Read(imgDerecha, 0, System.Convert.ToInt32(derecho.Length));
derecho.Close();
this.textBox1.Text = imgDerecha[0].ToString() + " " + imgDerecha[1].ToString();


y luego con la BD antes de asignar la imagen leemos los mismos bytes para saber si se almaceno correctamente asi podemos comparar con los bytes originales.
Puedes hacerlo con el primero y el ultimo o hacer un foreach para saber donde existe alguna diferencia.
Me parece que no estas guardando correctamente los bytes en la BD.
Pero tienes que hacer las pruebas para estar seguro en que parte tienes el problema.

-R IP
:0100
-A 100 
2826:0100 MOV AH,09
2826:0102 MOV DX,109
2826:0105 INT 21
2826:0105 MOV AH,08
2826:0105 INT 21
2826:0107 INT 20
2826:0109 DB 'MI NICK ES CODELIVE.$' 
2826:0127 
-R BX
:0000
-R CX
:20
-N CODELIVE.COM
-W

Hartigan

Cita de: 43H4FH44H45H4CH49H56H45H en 15 Junio 2010, 15:58 PM
Cita de: Hartigan en 15 Junio 2010, 13:48 PM
Bueno no hay manera. He seguido tropecientos tutoriales y esque hay algo que no va bien. En la parte en la que se hace la conversión de bytes al tipo image, toma el valor null, no se porqué y entonces no le asigna nada... Creo que voy a desistir y a probar el método de almacenar solo la dirección local de la imágen.

Puedes leer que almaceno en la BD sin asignar la imagen al picturebox.
Si leemos algunos bytes antes de almacenarlos:

Código (csharp) [Seleccionar]
System.IO.Stream derecho = new System.IO.MemoryStream();
this.pictureBox1.Image.Save(derecho, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] imgDerecha = new byte[derecho.Length];
derecho.Position = 0;
derecho.Read(imgDerecha, 0, System.Convert.ToInt32(derecho.Length));
derecho.Close();
this.textBox1.Text = imgDerecha[0].ToString() + " " + imgDerecha[1].ToString();


y luego con la BD antes de asignar la imagen leemos los mismos bytes para saber si se almaceno correctamente asi podemos comparar con los bytes originales.
Puedes hacerlo con el primero y el ultimo o hacer un foreach para saber donde existe alguna diferencia.
Me parece que no estas guardando correctamente los bytes en la BD.
Pero tienes que hacer las pruebas para estar seguro en que parte tienes el problema.

Tiene que ser eso, que se guardan mal los datos, porque incluso con el programa de D4N93R me sale el mismo error en el listview (parámetro no válido).

Voy a probar a ver. Muchas gracias.

Hartigan

#32
Bueno pues efectivamente ahí está el problema.

Os publico como hago para guardar y para leer de la base de datos a ver si veis el error

Guardar:

Código (csharp) [Seleccionar]

private void button_AceptarNC_Click(object sender, EventArgs e)
       {
           bool exito = false;
           //Primero copiamos las strings
           string[] datos = new string[33];
           int imgLength = 0;

           /*string temp = Path.GetTempFileName();
           FileStream fs = new FileStream(temp, FileMode.OpenOrCreate, FileAccess.ReadWrite);*/

           System.IO.Stream derecho = new System.IO.MemoryStream();
           this.pictureBox_FotoImagen.Image.Save(derecho, System.Drawing.Imaging.ImageFormat.Jpeg);
           byte[] img = new byte[derecho.Length];
           derecho.Position = 0;
           derecho.Read(img, 0, System.Convert.ToInt32(derecho.Length));
           derecho.Close();
           this.textBox1.Text = img[0].ToString() + " " + img[1].ToString() + " " + img[2].ToString() + " " + img[3].ToString();
           

           
           //System.IO.Stream stream = new System.IO.MemoryStream();

           datos[0] = this.textBox_Titulo.Text;
           datos[1] = this.textBox_Nombre.Text;
           datos[2] = this.textBox_SegundoNombre.Text;
           datos[3] = this.textBox_PrimerApellido.Text;
           datos[4] = this.textBox_SegundoApellido.Text;
           datos[5] = this.textBox_Sobrenombre.Text;
           datos[6] = this.textBox_Direccion.Text;
           datos[7] = this.textBox_Ciudad.Text;
           datos[8] = this.textBox_Provincia.Text;
           datos[9] = this.textBox_CodigoPostal.Text;
           datos[10] = this.textBox_Pais.Text;
           datos[11] = this.textBox_Prefijo_Telefono.Text + this.textBox_Telefono.Text;
           datos[12] = this.textBox_Movil.Text;
           datos[13] = this.textBox_Fax.Text;
           datos[14] = this.listBox_Email.Text;
           datos[15] = this.textBox_Web.Text;
           datos[16] = this.textBox_Twitter.Text;
           datos[17] = this.textBox_Facebook.Text;
           datos[18] = this.textBox_Direccion_Trabajo.Text;
           datos[19] = this.textBox_Ciudad_Trabajo.Text;
           datos[20] = this.textBox_Provincia_Trabajo.Text;
           datos[21] = this.textBox_CP_Trabajo.Text;
           datos[22] = this.textBox_Pais_Trabajo.Text;
           datos[23] = this.textBox_Organizacion_Trabajo.Text;
           datos[24] = this.textBox_Puesto_Trabajo.Text;
           datos[25] = this.textBox_Departamento_Trabajo.Text;
           datos[26] = this.textBox_Oficina_Trabajo.Text;
           datos[27] = this.textBox_Telefono_Trabajo.Text;
           datos[28] = this.textBox_Fax_Trabajo.Text;
           datos[29] = this.comboBox_Sexo.Text;
           datos[30] = this.textBox_Pareja.Text;
           datos[31] = this.listBox_Hijos.Text;
           datos[32] = this.richTextBox_Comentario.Text;


           /*this.pictureBox_FotoImagen.Image.Save(fs, System.Drawing.Imaging.ImageFormat.Jpeg);
           fs.Position = 0;

           imgLength = Convert.ToInt32(fs.Length);
           byte[] img = new byte[imgLength];
           fs.Read(img, 0, imgLength);
           fs.Close();*/

           String sentenciaSQL = "insert into contactos values('" + datos[0] + "','" + datos[1] + "','" + datos[2] + "','" +
                    datos[3] + "','" + datos[4] + "','" + datos[5] + "','" + datos[6] + "','" + datos[7] + "','" + datos[8] + "','" +
                    datos[9] + "','" + datos[10] + "','" + datos[11] + "','" + datos[12] + "','" + datos[13] + "','" + datos[14] + "','" +
                    datos[15] + "','" + datos[16] + "','" + datos[17] + "','" + datos[18] + "','" + datos[19] + "','" + datos[20] + "','" +
                    datos[21] + "','" + datos[22] + "','" + datos[23] + "','" + datos[24] + "','" + datos[25] + "','" + datos[26] + "','" +
                    datos[27] + "','" + datos[28] + "','" + datos[29] + "','" + datos[30] + "','" + datos[31] + "','" + datos[32] + "','" + img + "')";

           SqlConnection conexion = null;

           try
           {
               conexion = new SqlConnection(cadena_conexion);
               conexion.Open();

               SqlCommand cmd = new SqlCommand(sentenciaSQL, conexion);
               
               if ((1 != cmd.ExecuteNonQuery()))
               {
                   MessageBox.Show("Se ha producido un error al acceder a la fuente de datos", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                   exito = false;
               }
               else
               {
                   exito = true;
               }

           }
           catch (SqlException ex)
           {
               // MessageBox.Show(ex.InnerException.Message, "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
               MessageBox.Show(" ha producido un error al acceder a la fuente de datos", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
               exito = false;
           }
           finally
           {
               if (conexion != null)
               {
                   if (conexion.State == ConnectionState.Open)
                   {
                       conexion.Close();
                   }
               }
           }
if (exito)
           {
               MessageBox.Show("Contacto añadido con exito", "Éxito", MessageBoxButtons.OK, MessageBoxIcon.Information);
               this.Close();
           }
           else
           {
               MessageBox.Show("No se ha podido añadir el contacto", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
               this.Close();
           }

           
           


       }
     


Ahora como leo:

Código (csharp) [Seleccionar]

public Interfaz_Datos_Contacto()
       {
           InitializeComponent();

           
           string cadena_conexion = @"Server= (local)\SQLEXPRESS; DataBase = agenda; Integrated Security = yes;";

           byte[] img = new byte[0];
           string[] datos = new string[33];

           

           String sentenciaSQL = "SELECT * FROM contactos WHERE apodo = 'pavolino'";

           SqlConnection conexion = null;

           try
           {
               conexion = new SqlConnection(cadena_conexion);
               SqlDataAdapter data_adapter = new SqlDataAdapter(sentenciaSQL, conexion);

               DataTable data_table = new DataTable();
               
               conexion.Open();
               data_adapter.Fill(data_table);

               datos = new string[33];
               datos[0] = data_table.Rows[0][0].ToString();
               datos[1] = data_table.Rows[0][1].ToString();
               datos[2] = data_table.Rows[0][2].ToString();
               datos[3] = data_table.Rows[0][3].ToString();
               datos[4] = data_table.Rows[0][4].ToString();
               datos[5] = data_table.Rows[0][5].ToString();
               datos[6] = data_table.Rows[0][6].ToString();
               datos[7] = data_table.Rows[0][7].ToString();
               datos[8] = data_table.Rows[0][8].ToString();
               datos[9] = data_table.Rows[0][9].ToString();
               datos[10] = data_table.Rows[0][10].ToString();
               datos[11] = data_table.Rows[0][11].ToString();
               datos[12] = data_table.Rows[0][12].ToString();
               datos[13] = data_table.Rows[0][13].ToString();
               datos[14] = data_table.Rows[0][14].ToString();
               datos[15] = data_table.Rows[0][15].ToString();
               datos[16] = data_table.Rows[0][16].ToString();
               datos[17] = data_table.Rows[0][17].ToString();
               datos[18] = data_table.Rows[0][18].ToString();
               datos[19] = data_table.Rows[0][19].ToString();
               datos[20] = data_table.Rows[0][20].ToString();
               datos[21] = data_table.Rows[0][21].ToString();
               datos[22] = data_table.Rows[0][22].ToString();
               datos[23] = data_table.Rows[0][23].ToString();
               datos[24] = data_table.Rows[0][24].ToString();
               datos[25] = data_table.Rows[0][25].ToString();
               datos[26] = data_table.Rows[0][26].ToString();
               datos[27] = data_table.Rows[0][27].ToString();
               datos[28] = data_table.Rows[0][28].ToString();
               datos[29] = data_table.Rows[0][29].ToString();
               datos[30] = data_table.Rows[0][30].ToString();
               datos[31] = data_table.Rows[0][31].ToString();
               datos[32] = data_table.Rows[0][32].ToString();
               
               

               
               
               foreach (DataRow myRow in data_table.Rows)
               {
                   img = (byte[])myRow["imagen"];
                   this.textBox1.Text = img[0].ToString() + " " + img[1].ToString() + " " + img[2].ToString() + " " + img[3].ToString();
                   
               }

           }
           catch (SqlException ex)
           {
               datos = null;
               MessageBox.Show("No se ha podido acceder a la fuente de datos", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
           }
           finally
           {
               if (conexion != null)
               {
                   if (conexion.State == ConnectionState.Open)
                   {
                       conexion.Close();              
                     
                   }
               }
           }
if ((datos != null) && ( img != null))
           {
               label_Nombre_Completo.Text = datos[1] + "" + datos[2] + "" + datos[3] + "" + datos[4];
               label_Titulo.Text = datos[0];
               label_Nombre.Text = datos[1];
               label_SegundoNombre.Text = datos[2];
               label_PrimerApellido.Text = datos[3];
               label_SegundoApellido.Text = datos[4];
               label_Sobrenombre.Text = datos[5];
               label_Direccion.Text = datos[6];
               label_Ciudad.Text = datos[7];
               label_EstadoProvincia.Text = datos[8];
               label_CodigoPostal.Text = datos[9];
               label_PaisRegion.Text = datos[10];
               label_Telefono.Text = datos[11];
               label_Movil.Text = datos[12];
               label_Fax.Text = datos[13];
               label_EMail.Text = datos[14];
               label_Web.Text = datos[15];
               label_Twitter.Text = datos[16];
               label_Facebook.Text = datos[17];
               label_Direccion_Trabajo.Text = datos[18];
               label_Ciudad_Trabajo.Text = datos[19];
               label_Provincia_Trabajo.Text = datos[20];
               label_CP_Trabajo.Text = datos[21];
               label_Pais_Trabajo.Text = datos[22];
               label_Organizacion_Trabajo.Text = datos[23];
               label_Puesto_Trabajo.Text = datos[24];
               label_Departamento_Trabajo.Text = datos[25];
               label_Oficina_Trabajo.Text = datos[26];
               label_Telefono_Trabajo.Text = datos[27];
               label_Fax_Trabajo.Text = datos[28];
               label_Sexo.Text = datos[29];
               label_Pareja.Text = datos[30];
               label_Hijos.Text = datos[31];
               richTextBox_Comentarios.Text = datos[32];
               
               

               MemoryStream stream = new MemoryStream(img);
               stream.Write(img, 0, img.Length);
               stream = new MemoryStream(img);
               this.pictureBox_FotoImagen.Image = Image.FromStream(stream);      

             

          }
           else
           {
               MessageBox.Show("Se ha producido un error al obtener los datos del contacto", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
           }



       }


He dejado el código donde compruebo los bytes y es ceirto que salen completamente distintos.

Salu2.

EDITO: la tabla de los contactos en la base de datos la tengo así:

Código (sql) [Seleccionar]

CREATE TABLE contactos(
titulo varchar(50),
nombre varchar(50) NOT NULL,
nombre2 varchar(50),
ape1 varchar(50) NOT NULL,
ape2 varchar(50),
apodo varchar(50) NOT NULL,
direccion varchar(150),
ciudad varchar(20),
provincia varchar(20),
cp varchar(10),
pais varchar(20),
telefono varchar(20),
movil varchar(20),
fax varchar(20),
email varchar(50),
web varchar(50),
twitter varchar(50),
facebook varchar(50),
direccion2 varchar(150),
ciudad2 varchar(20),
provincia2 varchar(20),
cp2 varchar(10),
pais2 varchar(20),
organizacion varchar(50),
puesto varchar(50),
departamento varchar(50),
oficina varchar(50),
telefono2 varchar(20),
fax2 varchar(20),
sexo varchar(10),
pareja varchar(50),
hijos varchar(100),
comentario varchar(500),
imagen image,

);

[D4N93R]

#33
Obviamente mi código era de referencia, y el listview lo cree para listar las imágenes.

Pero bueno ya solucionaste no?

EDIT:

Ahora que veo tu código tienes varios problemas que, creo, deberías echarle un ojo:

1.- Considera usar una struct o clase, para almacenar la data en vez de un arreglo
2.- Qué pasa si la imagen no es jpeg?
3.- Si la aplicación final va a usar SqlServerExpress no pongas las fotos en la BD porque la versión express tiene un límite de almacenamiento.
4.- Considera usar una clase de acceso a datos en vez de hacerlo todo en un método.
5.- En: String sentenciaSQL = "SELECT * FROM contactos WHERE apodo = 'pavolino'"; Seleccionas * , por lo que la consulta se hace más lenta, considera seleccionar las columnas que necesitas, así sean todas. Además de que nada asegura de que estas usando la imagen correcta al momento de cargar la data ya que estas usando un foreach en vez de validar si hay registros en el datatable y luego usar el primero.
6.- Con respecto a la base de datos, siempre utiliza un primarykey decimal, autoincremental, es decir, identity, con eso creas una identidad para el sistema.

Un saludo!

Hartigan

Cita de: D4N93R en 15 Junio 2010, 17:35 PM
Obviamente mi código era de referencia, y el listview lo cree para listar las imágenes.

Pero bueno ya solucionaste no?

ya me imaigno. Que va tio, me sigue pasando lo mismo. El problema es como dice el compañero 43H4FH44H45H4CH49H56H45H  que los datos que guardo y los que recojo son completamente distintos. Al guardar los bytes son: 255 216 255 224....... y al leer de la base de datos, la variable img tiene los siguientes bytes: 83 121 115 116...... como puedes ver no se parecen en nada. Entonces debe ser o que guardo mal, o que recojo mal, pero esque he seguido vuestros códigos y debería estar bien, no veo el fallo por ningun lado... A ver si me podeis ayudar.

Saludos y perdonar todas las molestias que estoy causando.

Gracias.

[D4N93R]


43H4FH44H45H4CH49H56H45H

@Hartigan en el insert solo inserta la imagen y un string para la consulta, luego prueba nuevamente que valores guarda.

Código (sql) [Seleccionar]
INSERT INTO <nombre_tabla>
[(<campo1>[,<campo2>,...])]
values
(<valor1>,<valor2>,...);


debes especificar el campo y el valor para hacerlo.

-R IP
:0100
-A 100 
2826:0100 MOV AH,09
2826:0102 MOV DX,109
2826:0105 INT 21
2826:0105 MOV AH,08
2826:0105 INT 21
2826:0107 INT 20
2826:0109 DB 'MI NICK ES CODELIVE.$' 
2826:0127 
-R BX
:0000
-R CX
:20
-N CODELIVE.COM
-W

43H4FH44H45H4CH49H56H45H

Una cosa mas, estas utilizando:

Código (csharp) [Seleccionar]
'" + img + "'

saca las dobles comillas.

-R IP
:0100
-A 100 
2826:0100 MOV AH,09
2826:0102 MOV DX,109
2826:0105 INT 21
2826:0105 MOV AH,08
2826:0105 INT 21
2826:0107 INT 20
2826:0109 DB 'MI NICK ES CODELIVE.$' 
2826:0127 
-R BX
:0000
-R CX
:20
-N CODELIVE.COM
-W

[D4N93R]

Ya probé el código de escritura que usas, funciona bien, ahora, yo creo que el problema que tienes esta en la lectura, o carga de data . Específicamente akí:

Código (csharp) [Seleccionar]

foreach (DataRow myRow in data_table.Rows)
{
     img = (byte[])myRow["imagen"];
     this.textBox1.Text = img[0].ToString() + " " + img[1].ToString() + " " + img[2].ToString() + " " + img[3].ToString();
}


En donde estas recorriendo un datatable que supuestamente debería tener un solo registro.

Si por casualidad te vienen dos vas a mostrar la imagen que no es, o pueede que sea hasta data corrupta que tengas en un registro mientras hacías las pruebas. y por eso te da error.

Entonces, añadres un brake en el foreach, cosa que es mala práctica, o lo haces de ésta manera:

Código (csharp) [Seleccionar]

if(data_table.Rows.Count>0)
{
     DataRow myRow = data_table.Rows[0];
     img = (byte[])myRow["imagen"];
     this.textBox1.Text = img[0].ToString() + " " + img[1].ToString() + " " + img[2].ToString() + " " + img[3].ToString();
}

Hartigan

Cita de: D4N93R en 15 Junio 2010, 17:35 PM
Obviamente mi código era de referencia, y el listview lo cree para listar las imágenes.

Pero bueno ya solucionaste no?

EDIT:

Ahora que veo tu código tienes varios problemas que, creo, deberías echarle un ojo:

1.- Considera usar una struct o clase, para almacenar la data en vez de un arreglo
2.- Qué pasa si la imagen no es jpeg?
3.- Si la aplicación final va a usar SqlServerExpress no pongas las fotos en la BD porque la versión express tiene un límite de almacenamiento.
4.- Considera usar una clase de acceso a datos en vez de hacerlo todo en un método.
5.- En: String sentenciaSQL = "SELECT * FROM contactos WHERE apodo = 'pavolino'"; Seleccionas * , por lo que la consulta se hace más lenta, considera seleccionar las columnas que necesitas, así sean todas. Además de que nada asegura de que estas usando la imagen correcta al momento de cargar la data ya que estas usando un foreach en vez de validar si hay registros en el datatable y luego usar el primero.
6.- Con respecto a la base de datos, siempre utiliza un primarykey decimal, autoincremental, es decir, identity, con eso creas una identidad para el sistema.

Un saludo!


hola, gracias. te comento:

1. lo intentaré hacer así xD
2. Eso es lo que me preguntaba yo unos post más atrás.
3. Seguramente termine usando mysql, de momento ando probando con imágenes pequeñajas. xD
4. Sí, en mi código lo hago por separado, ya que utilizo un patron dao y el acceso lo hago en otra clase.
5. Pero si quiero seleccionar todos los datos??? no entiendo muy bien como se haría..
6. Sí, ahora solo estoy de pruebas, luego tendré que usar un primary key para hacer las búsquedas.


Cita de: 43H4FH44H45H4CH49H56H45H en 15 Junio 2010, 18:14 PM
@Hartigan en el insert solo inserta la imagen y un string para la consulta, luego prueba nuevamente que valores guarda.

Código (sql) [Seleccionar]
INSERT INTO <nombre_tabla>
[(<campo1>[,<campo2>,...])]
values
(<valor1>,<valor2>,...);


debes especificar el campo y el valor para hacerlo.

No entiendo muy  bien como sería.... dices que le pase la imagen y un array para los datos???...

Cita de: 43H4FH44H45H4CH49H56H45H en 15 Junio 2010, 18:25 PM
Una cosa mas, estas utilizando:

Código (csharp) [Seleccionar]
'" + img + "'

saca las dobles comillas.

ok, voy a probar a ver.

Muchas gracias a los 2.