Leer una Imagen de una Base de Datos Contenido 1. 2. 3. 4. 5.
Introducción Una Base de Datos de Ejemplo Construyendo una Interfaz Gráfica Leyendo la Imagen Conclusión
1. Introducción En este artículo cubriremos el proceso de leer una imagen de una base de datos de SQL Server, basándonos en un ejemplo de un pequeño catálogo de 'Productos'. El almacenamiento de imágenes en bases de datos no suele ser la mejor solución para el tratamiento de imágenes en las aplicaciones enlazadas a datos; sin embargo, en algunos casos es necesaria esta práctica cuando se desea aprovechar las capacidades del SGBD que se haya elegido. Ahora veremos la forma de leer una imagen desde una base de datos SQL Server que ha sido guardada, tal como se describe en el artículo 'Almacenar una imagen en una base de datos'. Principio de la página
2. Una Base de Datos de Ejemplo Para este ejemplo usaremos la misma base de datos y tabla que se usó en el artículo 'Almacenar una imagen en una base de datos'. La definición es la siguiente:
CREATE TABLE Products ( id int NOT NULL , name nvarchar (80) NOT NULL, quantity int NOT NULL, price smallmoney NOT NULL, productImage image NULL , CONSTRAINT PK_Products PRIMARY KEY CLUSTERED (id) ) Visualmente, en el administrador corporativo, tendría el aspecto que muestra la Figura 1:
Figura 1. Volver al texto. Principio de la página
3. Construyendo una Interfaz Gráfica Construiremos una pequeña interfaz gráfica que nos servirá para obtener los datos de los productos, entre ellos, la imagen. El aspecto del formulario será el que muestra la Figura 2:
Figura 2. Volver al texto. Principio de la página
4. Leyendo la Imagen Para leer los datos del registro (incluyendo la imagen) de la base de datos en base a la clave ingresada en el campo 'Clave del producto', extraeremos la información al hacer clic sobre el botón Buscar y usando el siguiente código:
private void searchButton_Click(object sender, System.EventArgs e) { try { // Creando objetos de datos. System.Data.DataSet ds = new System.Data.DataSet(); System.Data.SqlClient.SqlDataAdapter da = new System.Data.SqlClient.SqlDataAdapter("SELECT * FROM Products WHERE id = @id", @"Data Source=(local);Initial Catalog=store;Integrated Security=SSPI"); // Añadiendo el parámetro da.SelectCommand.Parameters.Add("@id", System.Data.SqlDbType.Int); // Estableciendo el valor del parámetro da.SelectCommand.Parameters["@id"].Value = int.Parse(idBox.Text);
// Se recuperan los datos da.Fill(ds, "products"); // Se verifica la existencia del registro if (ds.Tables["products"].Rows.Count != 0) { // Se establecen los valores en el formulario nameBox.Text = ds.Tables["products"].Rows[0]["name"].ToString(); quantityBox.Text = ds.Tables["products"].Rows[0]["quantity"].ToString(); priceBox.Text = ds.Tables["products"].Rows[0]["price"].ToString(); // El campo productImage primero se almacena en un buffer byte[] imageBuffer = (byte[]) ds.Tables["products"].Rows[0]["productImage"]; // Se crea un MemoryStream a partir de ese buffer System.IO.MemoryStream ms = new System.IO.MemoryStream(imageBuffer); // Se utiliza el MemoryStream para extraer la imagen pictureBox.Image = Image.FromStream(ms); } else { MessageBox.Show("El producto no existe"); } } catch (System.Exception ex) { MessageBox.Show(ex.Message); } } Examinaremos este código a continuación; primero se crea un objeto DataSet en el cual se colocarán los datos después de traerlos de la base de datos; después se crea un objeto SqlDataAdapter con la consulta (SELECT) como primer parámetro y la cadena de conexión, como segundo. Se añade un parámetro a la colección de parámetros del comando 'SelectCommand' y se establece su valor. Seguidamente, se ejecuta la consulta para extraer los datos de la base de datos; en la sentencia if se prueba si se encontró el registro, en caso contrario muestra un mensaje. Si se lo encuentra, se establecen las propiedades de los controles con los datos recuperados incluyendo la imagen; en este punto lo que se hace es usar un byte[ ] para referenciar los datos, a partir de este arreglo crear un flujo a memoria, un MemoryStream, y entonces usar el método estático de la clase Image, Image.FromStream(...), mediante el cual se construirá la imagen a partir del MemoryStream. El resultado al ejecutar este programa y hacer clic sobre el botón buscar con 'Clave de producto' igual a 1, se muestra en la Figura 3:
Figura 3. Volver al texto. Principio de la página
5. Conclusión El almacenamiento de imágenes en la base de datos no es una técnica comúnmente utilizada ya que incrementa drásticamente el tamaño de la misma, de cada registro, entre otros inconvenientes; normalmente solo suele almacenarse la ruta de la imagen. Sin embargo, en algunas ocasiones es necesario almacenarlas cuando se quiere aprovechar las características de gestión de SGBD elegido, como por ejemplo en la definición de un plan de mantenimiento, automatizando las copias de seguridad donde incluiría todo el catálogo de imágenes junto con la copia de seguridad. La mejor elección de la forma como guardar las imágenes siempre dependerá del ambiente de operación de la aplicación. Cuando se elige guardar la imagen dentro de la base de datos, para recuperarla, se puede usar el proceso aquí mencionado; cuando se decide guardar la ruta de una imagen, tenemos que asegurarnos de que la imagen realmente exista y el proceso para cargar la imagen sería siempre a partir de un archivo (file).