Ir al contenido principal

Guardar imágenes en base de datos con ASP.NET


En esta entrada vamos a ver un método para guardar imágenes físicamente en una base de datos SQL Server utilizando ASP.NET. También se podría guardar otro tipo de archivo que no sea una imagen, en este ejemplo se creará una aplicación web que permita al usuario subir cualquier tipo de imagen y guarde la información en la base de datos. Después veremos una manera para recuperar y mostrar las imágenes en un control de imagen.

Preparar estructura de datos

En SQL Server existe un tipo de datos llamado image preparado para almacenar imágenes directamente en una columna. En realidad es un campo binario de (2,147,483,647 bytes) de longitud por lo que también podría utilizar un tipo de datos varbinary.

En este caso se utilizará un tipo de datos image.


Crear proyecto web

Abrir Visual Studio y crear un proyecto web vacio en lenguaje C# o Visual Basic.


A continuación hacer clic derecho sobre la solución y agregar un nuevo elemento al proyecto.


Seleccionar un formulario web forms o página aspx y establecerle un nombre.


Se utilizan tres controles para este ejemplo. Uno es el control FileUpload para permitir al usuario la subida de imágenes, el segundo control será un tipo Image para poder cargar la imagen en él y por último un tercer control que será un Button desde el que guardaremos la imagen en la base de datos.

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="index.aspx.vb" 
Inherits="index" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Guardar imagen en SQL Server</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Image runat="server" ID="img" />
        <br />
        <asp:FileUpload ID="FileUpload1" runat="server" />
        <br />
        <asp:Button runat="server" ID="btnGuardar" Text="Guardar" />
    </div>
    </form>
</body>
</html>

La vista de los controles será parecida a la siguiente.


El control FileUpload le proporciona al usuario una forma de enviar archivos desde su equipo hasta el servidor. Tiene un método HasFile para comprobar si el usuario a seleccionado algún archivo desde su equipo. También nos proporciona acceso al propio archivo en memoria con la propiedad PostedFile.

FileUpload1.PostedFile.InputStream

Para almacenar el archivo seleccionado en la base de datos necesitamos obtener un array de bytes del propio archivo. Podemos usar una función auxiliar para convertir un stream en una array de bytes.

Private Function GetStreamAsByteArray(ByVal stream As Stream) As Byte()
    Dim streamLength As Integer = Convert.ToInt32(stream.Length)
    Dim fileData As Byte() = New Byte(streamLength) {}

    stream.Read(fileData, 0, streamLength)
    stream.Close()

    Return fileData
End Function

Una vez tenemos un array de bytes podemos ejecutar una consulta de inserción para guardar la imagen.

Private Sub InsertarImagen(ByVal Imagen As Byte())
   Try
      Dim conexion As New SqlConnection("localhost")
      conexion.Open()
      Dim cmd As New SqlCommand("INSERT INTO PruebaImagen VALUES (@Imagen)", conexion)
      With cmd
         .Parameters.Add(New SqlParameter("@Imagen", SqlDbType.Image)).Value = Imagen
      End With
      cmd.ExecuteNonQuery()
      conexion.Close()
   Catch ex As Exception

   End Try
End Sub

Para comprobar el resultado de forma manual podemos ver que a guardado en la columna de la base de datos, si no a generado ningún error vereís algo parecido a lo siguiente.


Imports System.IO
Imports System.Data
Imports System.Data.SqlClient

Partial Class index
    Inherits System.Web.UI.Page

    Protected Sub btnGuardar_Click(sender As Object, e As System.EventArgs) Handles btnGuardar.Click
        GuardarImagenSQL()
    End Sub

    Private Sub GuardarImagenSQL()
        Try
            If Not FileUpload1.HasFile Then
                Return
            End If

            Dim Imagen() As Byte = GetStreamAsByteArray(FileUpload1.PostedFile.InputStream)

            InsertarImagen(Imagen)
        Catch ex As Exception
        End Try
    End Sub

    Private Function GetStreamAsByteArray(ByVal stream As Stream) As Byte()
        Dim streamLength As Integer = Convert.ToInt32(stream.Length)
        Dim fileData As Byte() = New Byte(streamLength) {}

        stream.Read(fileData, 0, streamLength)
        stream.Close()

        Return fileData
    End Function

    Private Sub InsertarImagen(ByVal Imagen As Byte())
        Try
            Dim conexion As New SqlConnection("Ruta de conexión con la base de datos")
            conexion.Open()
            Dim cmd As New SqlCommand("INSERT INTO PruebaImagen VALUES (@Imagen)", conexion)
            With cmd
                .Parameters.Add(New SqlParameter("@Imagen", SqlDbType.Image)).Value = Imagen
            End With
            cmd.ExecuteNonQuery()
            conexion.Close()
        Catch ex As Exception

        End Try
    End Sub
End Class

El siguiente paso es recuperar la imagen desde la base de datos y mostrarla en el control Image. Creamos una nueva página .aspx que gestionará el tratamiento de la imagen. Podemos llamarla por ejemplo imagen.aspx.

Partial Class imagen
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Try
            Dim conexion As New System.Data.SqlClient.SqlConnection("localhost")
            Dim cmd As New System.Data.SqlClient.SqlCommand
            Dim reader As System.Data.SqlClient.SqlDataReader
            cmd.CommandText = "SELECT TOP(1) FROM PruebaImagen"
            cmd.CommandType = System.Data.CommandType.Text
            cmd.Connection = conexion
            conexion.Open()
            reader = cmd.ExecuteReader()
            Response.ContentType = "img/png"
            If reader.Read Then
                Response.BinaryWrite(reader("IMAGEN"))
            End If
            conexion.Close()
        Catch ex As Exception

        End Try
    End Sub
End Class

En el load de la página principal tendremos que escribir el siguiente código para redirigir a la página imagen.

Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
   img.ImageUrl = "imagen.aspx"
End Sub

Comentarios

  1. Gracias, tenia muchas horas de busqueda tratando de mostrar las imagenes

    ResponderEliminar
  2. La imagen no se muestra, no la puedo ver broder.. cómo sería??

    ResponderEliminar
  3. No entiendo la parte de la lectura, además sale error que no le capturas:
    "el formato de la cadena de inicialización no se ajusta a la especificacion que comienza en el indice 0"

    ResponderEliminar

Publicar un comentario