post icon

Mostrar imagen almacenada en la base de datos con Asp.Net

Cargar imagen desde ficheros del disco no es mucha ciencia incluso con HTML puro, el problema comienza cuando ya tenemos una base de datos que tiene almacenadas dentro de ella imágenes en campos binarios o BLOB.

Como no hay ningún tag que cargue directamente ficheros binarios, ni tampoco funciona el clásico sistema de programación Desktop en donde hacemos esa asignación directa. En Web tenemos que ingeniarnos un poco más para lograr el efecto esperado. Con Asp.Net al menos se nos hace más fácil ésta tarea.

Hagamos un ejemplo con SQL Server teniendo la siguiente tabla con algunos datos cargados. (No esta precisamente normalizado es para un simple ejemplo, no se fíen de su estructura).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
CREATE TABLE [dbo].[Empleado](
	[IdEmpleado] [int] IDENTITY(1,1) NOT NULL,
	[Nombres] [varchar](50) NOT NULL,
	[Apellidos] [varchar](50) NOT NULL,
	[Email] [varchar](50) NULL,
	[Telefono] [varchar](50) NULL,
	[Direccion] [varchar](50) NULL,
	[Ciudad] [varchar](50) NULL,
	[Pais] [varchar](50) NULL,
	[Departament] [varchar](50) NOT NULL,
	[Cargo] [varchar](50) NOT NULL,
	[FechaIngreso] [date] NOT NULL,
	[Salary] [money] NOT NULL,
	[Memo] [varchar](max) NULL,
	[Foto] [image] NULL
	[DocId] [varchar](50) NOT NULL
 CONSTRAINT [PK_Empleado] PRIMARY KEY CLUSTERED
(
	[IdEmpleado] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
 
GO
 
CREATE PROCEDURE [dbo].[ScalarFotoEmpleado]
AS
	SET NOCOUNT ON;
SELECT Foto FROM Empleado
 
GO
 
CREATE PROCEDURE [dbo].[SelectEmpleadoByDoc]
(
	@DocId varchar(50)
)
AS
	SET NOCOUNT ON;
SELECT        IdEmpleado, Nombres, Apellidos, Email, Telefono, Direccion, Ciudad, Pais, Departament, Cargo, FechaIngreso, Salary, Memo, Foto, RFID, DocId
FROM            Empleado
WHERE        (DocId = @DocId)

También crearemos rapidamente un DataSet.xsd dentro de la carpeta App_Code con el mapeo de la siguiente tabla, vean en la imagen (dejo a cargo de ustedes la creacion de los querys)

Como en Asp podemos devolver un conjunto binario pero no asignarlo directamente a un cuadro de imagen lo que haremos aprovecharnos de esto en vez de considerarlo una desventaja. Creamos un WebForm nuevo llamado RetornarImagen.aspx que no contendra nada a parte del siguiente codigo en el metodo Load.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using DataSetPrototypeTableAdapters;
using Image = System.Drawing.Image;
 
public partial class RetornarImagen : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Request.QueryString["IdEmpleado"] == null) return;
 
        var ta = new EmpleadoTableAdapter();
        var image = (byte[])ta.ScalarEmpleadoFoto(Convert.ToInt32(Request.QueryString["IdEmpleado"]));
 
        if (image != null)
        {
            Response.ContentType = "image/jpeg";
            using (var ms = new MemoryStream(image))
            {
                using (var jpg = (Bitmap)Image.FromStream(ms))
                {
                    jpg.Save(Response.OutputStream, ImageFormat.Jpeg);
                }
            }
        }
        else
        {
            Response.Write(Resources.TextoUtil.SinImagen);
        }
    }
}

Lo que hará esto es recibir por GET el Id del empleado que queremos recuperar su Foto, finalmente imprimirá sola la imagen en todo el browser, el mismo lo capturaremos desde la propiedad ImageURL del picture, veamos.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
private void Buscar()
    {
        try
        {
            if (txtSearch.Text == String.Empty)
                throw new Exception(errorCargarSearch.Text);
 
            var ta = new EmpleadoTableAdapter();
            DataTable dt = rdbId.Checked ? ta.GetEmpleadoById(Convert.ToInt32(txtSearch.Text)) : ta.GetEmpleadoByDoc(Convert.ToString(txtSearch.Text));
 
            if (dt.Rows.Count < 1)
                throw new Exception(errorSinFilas.Text);
 
            lblIdEmpleado.Text = dt.Rows[0]["IdEmpleado"].ToString();
            txtNombre.Text = dt.Rows[0]["Nombres"].ToString();
            txtApellido.Text = dt.Rows[0]["Apellidos"].ToString();
            txtEmail.Text = dt.Rows[0]["Email"].ToString();
            txtTelefono.Text = dt.Rows[0]["Telefono"].ToString();
            txtDireccion.Text = dt.Rows[0]["Direccion"].ToString();
            txtCiudad.Text = dt.Rows[0]["Ciudad"].ToString();
            txtPais.Text = dt.Rows[0]["Pais"].ToString();
            cboDepartamento.Value = dt.Rows[0]["Departament"].ToString();
            cboCargo.Value = dt.Rows[0]["Cargo"].ToString();
            cboFechaIngreso.Value = dt.Rows[0]["FechaIngreso"].ToString();
            txtSalario.Text = dt.Rows[0]["Salary"].ToString();
            txtMemo.Text = dt.Rows[0]["Memo"].ToString();
            txtDocumento.Text = dt.Rows[0]["DocId"].ToString();
            imgFoto.ImageUrl = "~/RetornarImagen.aspx?IdEmpleado=" + dt.Rows[0]["IdEmpleado"]; // aqui es donde aprovechamos la pagina anteriormente creada.
 
            btnGuardar.Enabled = true;
            btnEliminar.Enabled = true;
        }
        catch (Exception ex)
        {
            popUp.Text = ex.Message;
            popUp.ShowOnPageLoad = true;
        }
    }

El mismo quedaria algo asi (Click en el para verlo mejor):

Comentarios desde Facebook:

  1. jjj MEXICO Mozilla Firefox Windows
    22 mayo 2013 at 13:54 #

    Buen dia, tengo mi pagina para subir imagenes a la base de datos, hoy encontre tu propuesta para mostrarlas en asp, funciona. Pero si subo imagenes en formatos png u otro que no sea jpg no me la pinta, alguna idea?

  2. Talia MEXICO Google Chrome Windows
    25 abril 2012 at 13:18 #

    hola disculpa m gustaria saber si fuera posible q m enviaras tu codigo q ya funciono, porq ami m causa muchos errores gracias

    • GeekZero PARAGUAY Google Chrome Windows
      25 abril 2012 at 14:04 #

      Ya no tengo los fuentes de esta sección, pero si me muestras tu error quizá te pueda ayudar..

  3. chelo BOLIVIA Google Chrome Windows
    22 abril 2012 at 03:33 #

    hola muy bueno tu aporte pero tengo problemas con el Response.Write(Resources.TextoUtil.SinImagen);
    si me das una manito

  4. Rafael DOMINICAN REPUBLIC Mozilla Firefox Windows
    19 abril 2012 at 16:00 #

    Exelente codigo funciona… Gracias

  5. lalo_esfa MEXICO Internet Explorer Windows
    26 septiembre 2011 at 04:32 #

    De huevos jajajajaja

    Gracias por el codigo y la ayuda,
    solo una pregunta, para que sirve la siguiente linea de codigo

    Response.Write(Resources.TextoUtil.SinImagen);

    ya que me marco error en Resources

  6. mauricio garcia COLOMBIA Google Chrome Windows
    21 septiembre 2011 at 15:58 #

    GeekZero buenas tardes,,,,sera que me puede pasar el codigo,,,de mostrar la imagen almacenada en la base de datos

  7. ser ARGENTINA Mozilla Firefox Windows
    10 octubre 2010 at 12:06 #

    Gracias a todos flacos me salvaron la vida

    • GeekZero PARAGUAY Google Chrome Windows
      10 octubre 2010 at 13:13 #

      Super que te haya servido ambos post :D

  8. GeekZero PARAGUAY Google Chrome Windows
    22 septiembre 2010 at 16:24 #

    EL código ha sido convertido por un programa, por lo que puede contener errores, pero te servirá ya de inspiración, crea una pagina nueva y en su load agrega este codigo

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    Protected Sub Page_Load(sender As Object, e As EventArgs)
    	If (Request.QueryString("IdEmpleado") = Nothing) Then return
     
    	Dim ta = new EmpleadoTableAdapter()
    	Dim image = CType(ta.ScalarEmpleadoFoto(Convert.ToInt32(Request.QueryString("IdEmpleado"))),Byte())
     
    	If image IsNot Nothing Then
    		Response.ContentType = "image/jpeg"
    		Using ms = new MemoryStream(image)
    			Using jpg = CType(Image.FromStream(ms),Bitmap)
    				jpg.Save(Response.OutputStream, ImageFormat.Jpeg)
    			End using
    		End using
    	Else
    		Response.Write(Resources.TextoUtil.SinImagen)
    	End if
    End Sub

    Recuerda que es un query que consulta solo una foto, y siempre debe devolver un solo registro y una sola columna (la foto a mostrar)
    Luego a esta pagina le seteas como el ImageURL de tu objeto image

  9. Ivan// PERU Mozilla Firefox Windows
    22 septiembre 2010 at 12:34 #

    hola, GeekZero bueno soy nuevo en esto del asp y demas. ja lo que pasa esque tengo un webform donde a partir de consultas extarigo datos de la BD Northwind, de la tabla employees, como su nombre, titulo y el problema es en mostrar la foto, encontré ejemplos pero en formularios VB, pero quisiera saber como es para asp pero con VB, porque todos los que encuentro es en c#, solo necesito saber como mostrar la foto nomas :)

    • GeekZero PARAGUAY Google Chrome Windows
      22 septiembre 2010 at 12:56 #

      Como te decía si tienes algo ya construido colócalo en el foro. Como no dispongo de mucho tiempo me costará hacer una “traducción” a VB al menos en un lapso corto de tiempo.
      Con la data que me pasas puedo ayudarte un poco con la lógica, primeramente olvídate del estilo de programación Desktop porque para cargar la imagen desde la BD es muy distinto el proceso.
      Debes crear un WebForm que solo muestre una foto y en su llamada Page_Load devuelves una imagen gracias al Response.Write (el mismo debe devolver un Stream a partir de tu consulta a la BD). Entonces en la página que cargará la imagen, donde este tu objeto de Imagen en su propiedad URL le pasas la dirección del form que devuelve una imagen, yo he usado parametros GET/Http para hacer dinámica la consulta, para practicar podrías hacerlo con parámetros estáticos.

      • Ivan// PERU Mozilla Firefox Windows
        22 septiembre 2010 at 13:15 #

        bueno haber mi webform consta de en un lisbox muestra las letras de la A-Z de acuero a eso muestra en un gridview los nombres de productos que coincidan con esas letras, y al seleccionar ese produc en el otro gridview muestra los detalles de el n° orden,la fecha… y al seleccionar ese producto en los labels muetra que realizó esa venta,el nombre, titulo y en un control image debe mostrar la foto y ahi nomas esta mi duda de como hacer eso, segun leí esta en binario y algunos usan controles picture y en asp no hay ese control, bueno te muestro hasta donde he avanzado.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        
        '--------------------------------------------------------------
        Imports System.Drawing.Bitmap
        Partial Class _Default
            Inherits System.Web.UI.Page
            Dim Objdatos As New Utilitario
            Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
                If Not Page.IsPostBack Then
                    For i = 65 To 90
                        ListBox1.Items.Add(Chr(i))
                    Next
                End If
            End Sub
            Protected Sub ListBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
                Dim letras As String = ""
                For i As Integer = 0 To ListBox1.Items.Count - 1
                    If ListBox1.Items(i).Selected = True Then
                        letras = letras + ListBox1.Items(i).ToString
                    End If
                Next
                GridView1.DataSource = Objdatos.Consultas_SQL("usp_list_product", letras)
                GridView1.DataBind()
            End Sub
            Protected Sub GridView1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView1.SelectedIndexChanged
                GridView2.DataSource = Objdatos.Consultas_SQL("usp_listar_ordenes", GridView1.SelectedRow.Cells(1).Text)
                GridView2.DataBind()
            End Sub
            Protected Sub GridView2_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView2.SelectedIndexChanged
                Dim orderID As String
                orderID = Me.GridView2.SelectedRow.Cells(1).Text
                Me.LblEmpleado.Text = Objdatos.Consultas_SQL("usp_empleado_ordenes", orderID).Rows(0).Item(0)
                Me.LblTitulo.Text = Objdatos.Consultas_SQL("usp_empleado_ordenes", orderID).Rows(0).Item(1)
            End Sub
        End Class
  10. GeekZero PARAGUAY Google Chrome Windows
    20 septiembre 2010 at 07:18 #

    Hola ivan, sería mejor si compartes tus dudas y las resolvemos. Así otros que luego vengan con las misma dudas ya tendrán la información a mano. Pasate por el foro y describe la situación que no entiendes o da error: http://www.devtroce.com/foro

  11. Ivan// PERU Mozilla Firefox Windows
    20 septiembre 2010 at 01:23 #

    amigo disculpa, no podrias compartir tu proyecto? o mandarlo por correo? te agradecería bastante… mi msn es silencio-dark@hotmail.com gracias ;)

Trackbacks/Pingbacks

  1. Subir imágenes a la Base de Datos con ASP.Net | DevTroce.com WordPress - 9 septiembre 2010

    [...] la entrada anterior veíamos como recuperar una imagen almacenada en la Base de Datos y mostrarlo en un control de imagen con Asp.Net, en ésta ocación haremos la tarea inversa, [...]

Responder