Guardar Imagen en base de datos. (c#)

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

0 Miembros y 1 Visitante están viendo este tema.

Hartigan

Hola de nuevo compañeros. Necesito guardar una imágen en la base de datos, y he mirao tutoriales pero no hay manera, porque yo intento guardarla como byte, pero no me covierte, me dice que no puedo convertir un System.Drawing.Image en byte[].

que puedo hacer?? como paso o convierto la imágen??.

gracias de antemano.

.mokk.

Pues yo lo tengo hecho tmb en un programa que hice anteriormente y lo hice con este tutorial

http://www.elguille.info/NET/ADONET/SQL2005Express/imagenes_base_SQLServer.htm

Tambien anteriormente cuando no sabia hacerlo, lo que hacia esque guardaba la imagen a un host o la enviava ahi o a una web local mia, y ya en la DB colocaba el link de la imagen.

Hartigan

gracias voy a probar, pero así leyendo por encima he visto esto:


img.Save(fs, System.Drawing.Imaging.ImageFormat.Png);


Si la imágen que yo he escogido anteriormente para mi picturebox no es png que hago??.

Es decir: yo tengo un formulario donde se agregan contactos (es una agenda) entonces cada contacto tendrá un picturebox con su imágen y unas serán en png, otras en jpg, otras gif... etc... Con eso todas las imágenes las convierte a png???. o como lo tendría que hacer sino...

Salu2

43H4FH44H45H4CH49H56H45H

Cuando necesite guardar imagenes en una BD los ejemplos que encontre primero guardaban la imagen en disco. Por eso yo lo hice de este modo:

Código (csharp) [Seleccionar]

System.IO.Stream derecho = new System.IO.MemoryStream();
this.picDerecha.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();


Código (csharp) [Seleccionar]
myRow["IDerecha"] = imgDerecha;

Cita de: Hartigan en 13 Junio 2010, 20:46 PM
gracias voy a probar, pero así leyendo por encima he visto esto:


img.Save(fs, System.Drawing.Imaging.ImageFormat.Png);


Si la imágen que yo he escogido anteriormente para mi picturebox no es png que hago??.

Solo cambias:

Código (csharp) [Seleccionar]
System.Drawing.Imaging.ImageFormat.Jpeg

por la extension que necesites.

-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]

No guardes imágenes en la Base De Datos, amenos de que esa columna esté físicamente almacenándose en otra partición o disco. Esto es por cuestiones de rendimiento y mantenimiento.

Lo mejor que puedes hacer es guardar la url o localpath (en caso de que sea web) o la dirección de red en caso de que sea Windows Form.

Se que es mucho más fácil almacenarlo en la base de datos, pero es algo que está fuera de las buenas prácticas.

43H4FH44H45H4CH49H56H45H

Cita de: D4N93R en 13 Junio 2010, 23:52 PM
No guardes imágenes en la Base De Datos, amenos de que esa columna esté físicamente almacenándose en otra partición o disco. Esto es por cuestiones de rendimiento y mantenimiento.

Lo mejor que puedes hacer es guardar la url o localpath (en caso de que sea web) o la dirección de red en caso de que sea Windows Form.

Se que es mucho más fácil almacenarlo en la base de datos, pero es algo que está fuera de las buenas prácticas.

Que mejor que lea la opinion de un moderador y participantes de technet:

http://social.technet.microsoft.com/Forums/en-SG/sqlserveres/thread/a16a512c-9d43-441d-8585-47840ef09de5

de la cual rescato lo que me parecio una de las mejores respuestas:
La del moderador:

CitarDejaré mi opinión también.

Ante este tipo de situaciones, me es complicado ser imparcial. Yo administro servidores de bases de datos, no ficheros. Si puedo evitarme esa gestión y mandar los ficheros a otra parte, pues mejor. Es un riesgo importante administrar una gestión documental, ya que el crecimiento suele ser impredecible. De pronto un día a alguien le da por escanear, no sé, las nóminas del último año y guardarlas en la gestión documental. Puede ser que sean 100 documentos (y no pasa nada) o puede que se trate de una de las mayores empresas de trabajo temporal del mundo y la habremos liado.

Sin embargo, estoy convencido de que gestionado todo ello desde SQL Server, el rendimiento sería muy superior. También se algo más de SQL Server que de File System. Y las últimas versiones de SQL Server han introducido numerosas mejoras en ese aspecto. Filestream es una de ellas, para mí, lo que ha mejorado Full Text Search me parece mucho más importante, aunque también depende del tipo de ficheros a introducir en la base de datos. Si son imágines, da un poco igual, ya que no vas a indexar nada más que los metadatos.

Jesús, testear y hacer una prueba comparativa de concepto (pero una prueba seria) es imprescindible. Y una cosa es segura: tendrás problemas, tanto si lo dejas en el file system como si lo dejas en el servidor de bases de datos. Más copias de seguridad, más entornos de pruebas, etc. Un volumen muy grande para administrar (algo que suele ir unido a este tipo de cosas) suele presentar toda una serie de complejidades adicionales.

Ahora @D4N93R podrias indicarme un enlace o referencia de porque esta fuera de las buenas practicas el almacenar imagenes dentro de una BD.

-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

Bueno, lo primero, gracias por las respuestas.

He estado probando y no hay manera. Me da un error en la linea:


this.picDerecha.Image.Save(derecho, System.Drawing.Imaging.ImageFormat.Jpeg);


y el error que me da es:

Error genérico en GDI+.

Alguna solución???

[D4N93R]

Si vas a almacenar las imágenes, o cualquier archivo dentro de la base de datos es mejor que lo hagas en otra particion o disco, por que? Defragmentación de indices y data, espacio en disco, condiciones del servidor, etc. Normalmente en apliaciones grandes el webserver está separado de la base de datos, en aplicaciones grandes,  por el mismo motivo.

Otros motivos? Muchos son relevantes o irrelevantes según el escenario.


  • Backup, tomar en cuenta el tamaño del la BD.
  • Es mucho más fácil acceder las imágenes desde el file system. COmo por ejemplo para verlas, o abrir algún documento
  • Muchos hosting cobrab adicional por el espacio en BD

Encontré también algunos links:

http://stackoverflow.com/questions/561447/store-pictures-as-files-or-in-the-database-for-a-web-app

Ahora, dependiendo del escenario puedes almacenar archivos en la base de datos, pero, te recomiendo que hagas que la base de dato almacene esa columna en otro disco.


@43H4FH44H45H4CH49H56H45H, he desarrollados muchos sistemas de negocios, aplicaciones, consultorías y asesorías, he respondido a la mayoría problemas de mis clientes, y he sido testigo del problema de almacenar imagenes y archivos en la base de datos.

@Hartigan: que tipo de aplicación haces? describe un poco más la situación.


Hartigan

#8
Vale ya lo he solucionado. Parece que al selecionar la imágen en el picture box algo no se guardaba bien y luego había conflicto. Ahora ya me va. En principio se me guarda en la base de datos, pero ahora me está fallando al leer de la base de datos.

D4N93R  Estoy haciendo una agenda electronica. Entonces para cada contacto se podrá seleccionar una imágen por eso de guardarla en la base de datos. Otra forma no se como hacerlo. Si dices que es mejor guardando solo la ruta pues la verdad que si me dijeras como te estaría agradecido.

En cualquier caso ahora a ver si me podeis ayudar con esto.

Para leer la imágen de la base de datos hago lo siguiente:

Código (csharp) [Seleccionar]

public override byte[] Obtener_Imagen_Contacto()
       {
           byte[] img = null;            

           String sentenciaSQL = "SELECT imagen 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);

               img = new byte[0];
               img = (byte[])data_table.Rows[0][0];

               

           }
           catch (SqlException ex)
           {
               img = 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();
                   }
               }              
           }
           return (img);
       }



luego desde el formulario, para que me cargue la imágen hago esto:

Código (csharp) [Seleccionar]

public Interfaz_Datos_Contacto(Factoria_DAO factoria)
       {
           InitializeComponent();

           factoriaDAO = factoria;

           MemoryStream stream = null;

           Gestor_Contacto gestor_contacto = new Gestor_Contacto();
           
           byte[] img = gestor_contacto.Obtener_Imagen_Contacto(factoriaDAO);

           stream = new MemoryStream(img);
          pictureBox_FotoImagen.Image = Image.FromStream(stream);



El error me lo da en la última linea. Me dice que el parametro no es válido.

Solución??

Gracias de antemano.

43H4FH44H45H4CH49H56H45H

#9
Lo puedes hacer asi:

Código (csharp) [Seleccionar]
byte[] MyData = new byte[0];
MyData = (byte[])myRow["IDerecha"];
int ArraySize = new int();
ArraySize = MyData.GetUpperBound(0);
System.IO.Stream derec = new System.IO.MemoryStream();
derec.Write(MyData, 0, MyData.Length);
picDerecha.Image = Image.FromStream(derec);


EDIT: Si quieres almacenar solo la ruta de la imagen, lo haces como texto. Osea solo guardas un string en la BD con la ruta donde se guardo la imagen, pero debes recordar como hacer el backup de dichas imagenes, o tb si quieres exportar tu BD.

-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