Leer una Imagen de una Base de Datos

Por Miguel Ortiz Falcón

Contenido

 1. Introducción
 2. Una Base de Datos de Ejemplo
 3. Construyendo una Interfaz Gráfica
 4. Leyendo la Imagen
 5. 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'.

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:

Bb972267.art260-img01-402x97(es-es,MSDN.10).jpg
Figura 1. Volver al texto.

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:

Bb972267.art260-img02-384x472(es-es,MSDN.10).jpg
Figura 2. Volver al texto.

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:

Bb972267.art260-img03-384x472(es-es,MSDN.10).jpg
Figura 3. Volver al texto.

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).

Bb972267.Miguel_Ortiz_Falcon(es-es,MSDN.10).gifMiguel Ortiz Falcón es Estudiante de la Ingeniería en Sistemas Computacionales del Instituto Tecnológico de Veracruz, en el que ha sido reconocido como integrante del cuadro de honor en varias oportunidades. Posee 7 años de experiencia como desarrollador y profesional independiente. Es colaborador activo del Grupo de Usuarios de C# y miembro de la Academia Latinoamericana de Seguridad Informática (ALSI), y ha actuado como ponente en conferencias de Microsoft en México. Ha obtenido 4 estrellas del programa Desarrollador Cinco Estrellas de Microsoft MSDN Latinoamérica y 2 de su nueva versión.
Principio de la página
Mostrar: