Ir al índice de .NET ADO.NET  - SQL Server 2005 Express
 

Usar imágenes de una base de SQL Server 2005

 
Publicado el 21/Mar/2007
Actualizado el 21/Mar/2007
Autor: Guillermo 'guille' Som

Cómo usar imágenes guardadas en una base de datos de SQL Server 2005 (guardar y recuperar una imagen en/de un campo de tipo image). Y como de costumbre, con código para VB como para C#.

 

Introducción:

En este artículo te voy a explicar (de la forma más sencilla posible) cómo trabajar con imágenes para guardarlas en una base de datos de SQL Server 2005.
Por supuesto también te explicaré cómo recuperar una imagen de la base de datos y mostrarla en un control de tipo PictureBox.

Para este ejemplo, voy a usar una clase muy simple en la que tengo definido dos métodos compartidos (o estáticos), uno de ellos te permitirá convertir una imagen en un array de tipo Byte (¡espera! ¡no te desesperes! ahora te explico porqué convertir una imagen a un array de bytes), y la otra para lo contrario, es decir, convertir un array de bytes en un objeto de tipo Image.
Lo de trabajar con un array de bytes es porque en realidad un campo de tipo image de SQL Server es un array de bytes. Sabiendo esto, puedes adivinar que el primer método servirá para poder guardar una imagen en el campo de la tabla y el segundo para leer el contenido de ese campo y poder usarlo como una imagen normal.

Aquí tienes el código de esos dos métodos, tanto para Visual Basic como para C#. Estos dos métodos están definidos en una clase llamada TablaNavegar y como ves son estáticos (compartidos), por tanto para usarlos no es necesario crear una instancia de esa clase, sino que se usarán indicando el nombre de la clase seguida del método a usar (en un momento te explico cómo usarlos).

Public Shared Function Image2Bytes(ByVal img As Image) As Byte()
    Dim sTemp As String = Path.GetTempFileName()
    Dim fs As New FileStream(sTemp, FileMode.OpenOrCreate, FileAccess.ReadWrite)
    img.Save(fs, System.Drawing.Imaging.ImageFormat.Png)
    fs.Position = 0
    '
    Dim imgLength As Integer = CInt(fs.Length)
    Dim bytes(0 To imgLength - 1) As Byte
    fs.Read(bytes, 0, imgLength)
    fs.Close()
    Return bytes
End Function

Public Shared Function Bytes2Image(ByVal bytes() As Byte) As Image
    If bytes Is Nothing Then Return Nothing
    '
    Dim ms As New MemoryStream(bytes)
    Dim bm As Bitmap = Nothing
    Try
        bm = New Bitmap(ms)
    Catch ex As Exception
        System.Diagnostics.Debug.WriteLine(ex.Message)
    End Try
    Return bm
End Function

 

public static byte[] Image2Bytes(Image img)
{
    string sTemp = Path.GetTempFileName();
    FileStream fs = new FileStream(sTemp, FileMode.OpenOrCreate, FileAccess.ReadWrite);
    img.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
    fs.Position = 0;
    //
    int imgLength = Convert.ToInt32(fs.Length);
    byte[] bytes = new byte[imgLength];
    fs.Read(bytes, 0, imgLength);
    fs.Close();
    return bytes;
}

public static Image Bytes2Image(byte[] bytes)
{
    if (bytes == null) return null;
    //
    MemoryStream ms = new MemoryStream(bytes);
    Bitmap bm = null;
    try
    {
        bm = new Bitmap(ms);
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.Message);
    }
    return bm;
}

El método Image2Bytes recibe como parámetro un objeto de tipo Image, crea un fichero temporal y lo guarda como PNG, lee el contenido de ese fichero y lo asigna a un array de tipo Byte, para finalmente devolver dicho array.

Por otro lado, el método Byte2Image recibe un array de bytes como parámetro, lo asigna a un objeto del tipo MemoryStream y ese "stream" lo utiliza para crear un objeto del tipo Bitmap, finalmente devuelve ese objeto que en el fondo es un objeto de tipo Image.

Como puedes comprobar la parte más simple es la de convertir el array de bytes en una imagen, operación que puedes realizar en una sola pasada, al menos si no haces ningún tipo de comprobación de error.

 

Veamos ahora cómo usar estos métodos.

El primer caso, será para asignar a un campo de tipo image de una tabla de SQL Server el contenido de un control PictureBox. En el siguiente código, se supone que la variable dr es del tipo DataRow y que el campo de la tabla en la que vamos a guardar la imagen se llama Foto, de igual forma el control que tiene la imagen se llama FotoPictureBox.

dr("Foto") = TablaNavegar.Image2Bytes(Me.FotoPictureBox.Image)
dr["Foto"] = TablaNavegar.Image2Bytes(this.FotoPictureBox.Image);

 

Para asignar la imagen que está guardada en la base de datos al control FotoPictureBox lo haremos de esta forma:

If dr("Foto") IsNot DBNull.Value Then
    Dim img As Image = TablaNavegar.Bytes2Image(CType(dr("Foto"), Byte()))
    If img IsNot Nothing Then
        Me.FotoPictureBox.Image = img
    End If
End If
if( dr["Foto"] != DBNull.Value )
{
    Image img = TablaNavegar.Bytes2Image((byte[])dr["Foto"]);
    if( img != null )
    {
        this.FotoPictureBox.Image = img;
    }
}

Por supuesto, esto también lo puedes hacer de una pasada, al menos si no quieres comprobar si el objeto leído de la base de datos no es un valor nulo ni el resultado devuelto por la función tampoco lo es.

 

Y esto es todo.

En el ZIP con el código tienes un proyecto de prueba tanto para Visual Basic como para C# (para usar con la versión 2005 de Visual Studio o con las versiones Express) en el que se usa la clase TablaNavegar y en el que se accede a una base de datos de SQL Server que está en la instancia de SQLEXPRESS. Esa base de datos se llama conImagenes y la tabla se llama conFotos.

Si quieres crear la base de datos, te comento que la estructura de la tabla es la siguiente:

Campo Tipo
ID int
Nombre   nvarchar(255)  
Foto image

El campo ID es un campo de identidad (auto incremental), mejor será que te lo muestre. En la figura 1 puedes ver la estructura de la tabla.

Figura 1. Estructura de la tabla de prueba
Figura 1. Estructura de la tabla de prueba

 

En el ZIP incluyo una copia de seguridad de la base de datos de prueba, para restaurar esa base de datos puedes leer lo que hace un rato publiqué, tal como está el código la instancia de SQL Server debe ser SQLEXPRESS, pero si la restauras en la instancia predeterminada de SQL Server tendrás que cambiar la cadena de conexión usada para acceder a la base de datos.
Sólo decirte que esa base de datos la tengo en el directorio: C:\Archivos de programa\Microsoft SQL Server\MSSQL.1\MSSQL\Data, por tanto si te da error al restaurarla, tendrás que cambiar la ubicación, pero eso ya te lo explico en el artículo del link anterior.

 


Aporta tu granito de arena...

 

Espero que te sea de utilidad.

Nos vemos.
Guillermo


Espacios de nombres usados en el código de este artículo:

System.Drawing
System.Data
 


Código de ejemplo (comprimido):

 

Fichero con el código de ejemplo: Imagenes_SQL1.zip - 43.9 KB

(MD5 checksum: 0829132FED4057D67415BCEBF3F5A8EE)

 

Fichero con la base de datos de ejemplo: conImagenes2.zip 290.0 KB

(MD5 checksum: 8DDC69B22265F7B8EBB18BDCEFA93F6D)

 


Ir al índice principal de el Guille

Valid XHTML 1.0 Transitional