FileUpLoad e ImagenThumbnail

Una de las limitaciones del control fileupload de asp.net 2.0 es que luego de seleccionar el archivo, en este caso una imagen, se requiere un botón adicional para subir la imagen al servidor y previsualizarla. Este post pretende mostrar una manera (lo que no significa que sea la única ni la mejor) de realizar ambos pasos, subir la imagen al servidor y realizar el thumbnail con solo seleccionar la imagen.

Se va utilizar Visual Studio 2005 y por ende asp.net 2.0 (probado para IE 6.0 en adelante y Mozilla-Firefox 2.0.6).

Los controles en la pagina van a ser:

-FileUpload (el de la version 2.0) (UBICACIONTMP – nombre del control)

-Un hidden control (UBICACION – nombre del control)

-Un control Image (IMAGEN – nombre del control)

-Un LinkButton visible pero sin la propiedad text, lo que lo convierte en invisible pero que viaja al explorador. Caso contrario no viaja (LinkPostBack – nombre del control) Se usan los siguientes namespace:

Se usan los siguientes namespace:

Imports System.IO
Imports System.Net
Imports System.Drawing.Imaging

En el código de vb.net

Una varible global dentro de la pagina:

Dim imgThum As String

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Response.BufferOutput = False ‘No se va a almacenar en el buffer
Response.Clear() ‘Borra toda la salida de contenido de la secuencia del búfer
Response.ClearHeaders() ‘Borra todos los encabezados de la secuencia del búfer
‘JS que entra en accion cuando se haga click en browse del control fileupload
UBICACIONTMP.Attributes.Add(“onclick”, “javascript:asignarRutaFoto();”)
‘JS para validar que apriete el boton browse con el mouse y no teclee la ruta a mano
UBICACIONTMP.Attributes.Add(“onkeypress”, “javascript:return validarkey();”)
End Sub

Private Sub MostrarImagen()
Dim strFileName As String = UBICACION.Value
Dim Filename As String = system.IO.Path.GetFileName(strFileName)
Dim objImage, objThumbnail As System.Drawing.Image
Dim strServerPath As String
Dim shtWidth As Integer
Dim shtHeight As Integer
strServerPath = Server.MapPath(“ImagenesCarpeta\”)
strFileName = strServerPath & Filename
Dim my_stream As IO.Stream = Nothing
Try
‘Creo un stream para poner la imagen y despues hacer un OBJ con el metodo fromStream que cierra el archivo. Esto es importante para que la imagen no quede abierto en el servidor.
my_stream = File.OpenRead(strFileName)
objImage = Drawing.Image.FromStream(my_stream)
shtWidth = 100
shtHeight = objImage.Height / (objImage.Width / shtWidth)
Response.Clear()
objThumbnail = objImage.GetThumbnailImage(shtWidth, _
shtHeight, Nothing, System.IntPtr.Zero)

imgThum = “~/ImagenesCarpeta/” + “TUM_” + + “TUM_” + Filename ‘Para saber que se trata de un thumbnail
objThumbnail.Save(Server.MapPath(“ImagenesCarpeta\”) + “TUM_” + Filename, ImageFormat.Jpeg)
IMAGEN.Visible = True
IMAGEN.ImageUrl = “~/ImagenesCarpeta/” + “TUM_” + Filename

Catch ex As Exception
Throw ex
Finally
objImage.Dispose()
objImage = Nothing
objThumbnail.Dispose()
objThumbnail = Nothing
my_stream.Dispose()
my_stream = Nothing
End Try
End
Sub

Private Function CargarFotografia() As String

Dim strFileName As String = UBICACIONTMP.PostedFile.FileName
Dim Filename As String = Path.GetFileName(strFileName)
Dim extension As String = Path.GetExtension(strFileName).ToLower

Try

If extension <> “.png” AndAlso extension <> “.jpg” AndAlso extension <> “.bmp” Then
Throw New Exception(“El archivo ingresado no es una imagen”)
End If
UBICACIONTMP.PostedFile.SaveAs(Server.MapPath(“\ImagenesCarpeta\”) + Filename)
UBICACION.Value = NombreImagenServidor(extension) ‘asigno el nuevo nombre de la img al hide
File.Move(Server.MapPath(“\ImagenesCarpeta\”) + Filename, _ Server.MapPath(“\ImagenesCarpeta\”+ UBICACION.Value))

Return UBICACION.Value

Catch ex As IOException
Throw
Catch ex As UnauthorizedAccessException
Throw
Catch ex As Exception
Throw
End Try

End Function

Public Function NombreImagenServidor(ByVal extension As String) As String
Dim nombre As String
Dim nRandom As New Random
nr As String = Convert.ToString(nRandom.Next(0, 32000))
nombre = “TMP_” + Format(Date.Today, “dd.MM.yyyy”) + “_” + nr + extension
nRandom = Nothing

Return nombre
End Function

Protected Sub linkPostBack_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles linkPostBack.Click
Try
If UBICACIONTMP.HasFile = True Then ‘ si tiene un archivo
CargarFotografia()
MostrarImagen()

End If
Catch ex As Exception
lblMensajes.Text = “Ha ocurrido la Siguiente Excepcion: “ & ex.Message
End Try
End Sub

Y del lado del cliente se utiliza este script que me permite correr un ciclo hasta que el usuario le de click (luego de elegir la imagen) al botón aceptar, ahí es donde realizo un postback

<script language=”JavaScript” type=”text/javascript”>
var x=5000;
var Guardar;
function asignarRutaFoto()
{
var tiempo,tiempo2;
if(x>=0)
{
x-=1;
if (document.form1.UBICACIONTMP.value==“”)
{ tiempo2=setTimeout(“asignarRutaFoto()”,50); }
else
{document.form1.UBICACION.value=document.form1.UBICACIONTMP.value; x=-1;
__doPostBack(‘linkPostBack’,); }
}

}
function validarkey()
{
// Para que use el browse y no teclee la ruta
alert (“Presione el boton Browse para buscar una foto”)
return false;
}</script>

Esta es la pagina incial:
Foto 1

Esta es la pagina luego de seleccionar la imagen:

foto 2

Asi queda el directorio donde se almacenan las imagenes, la que comienza con TUM es para visualizar el Thumbnail y la otra es la imagen real.

foto 3

Saludos, espero les sea util a quien lo lea.

Descargar el proyecto aquí

ACTUALIZACION DE DESCARGAS (19/11/2011)

SKYDRIVE

Anuncios

17 comentarios sobre “FileUpLoad e ImagenThumbnail

  1. Q tal me ha servido de mucho tu articulo, pero quisiera saber como le puedo hacer para mostrar la imagen agregando un boton, y al momento de darle click al boton mostrar la imagen seleccionada en un control image para luego guardar todo el registro en la base de datos, gracias…

  2. bueno leo, mira en este momento no tengo un VS 2005 para poder probar lo que te digo con el codigo, pero lo que podes hacer es cuando se ejecuta el evento click de LinkPostBack, osea cuando seleccionas una imagen fijate q yo ahi llamo a CargarFotografia() y MostrarImagen() vos ahi podes hacer lo mismo pero dejarlo oculto por ejemplo poniendo algo asi Nombre_del_Control_a_Ocultar.Style(“display”) = “none” (para que esto funcione el control o el TD o TR tiene que ser runat=server) , despues de esta linea IMAGEN.ImageUrl = “~/ImagenesCarpeta/” + “TUM_” + Filename y seguido de eso le mostras un boton y cuando el tipo le da click al boton podes hacer una funcion JS que directamente muestre lo que vos ya tenes en pantalla pero oculto algo asi como:
    var ctl=”Nombre_del_Control_a_Mostrar”;
    document.getElementById(ctl).style[‘display’]=”;
    eso en el onclick de ese boton(en un script en la pagina), no lo testie pero tendria que funcionar, y para despues mandar la imagen a la Base tendrias que modificar lo que hago yo (osea guardarla en jpg en el servidor) aca encontre algo en la web, esta en C#, http://www.netveloper.com/contenido2.aspx?IDC=359_0 ,lo que podes hacer es guardar el objeto Byte (byteImage) en session y cuando decidis mandarlo a la base lo mandas con todo junto porque en el link que te pase lo mande de una a la Base.
    Cuando tenga a mano un VS2005 lo voy a modificar para adaptar esto de mandarlo a la BD en lugar de guardarlo en una carpeta.
    Espero te sirva!

  3. Hola Fernando !!
    Excelente articulo… Además de que te explicas muy bien, todo lo entendi a la perfeccion. a la primera me salio.
    Me sirvio de mucho, yo queria guardara inmediatamente al momento de buscar la imagen en el fileupload sin tener q agregar un boton de cargar… q era lo que yo hacia.
    Ya ahora solo voy a ajustarlo para q me deje no solo guardar imagenes sino q tambien archivos.
    Gracias!!
    Y espero sigas con estos articulos.

  4. primero lo hice funcionar tu proy, pero una ves que lo lleve a mi proy todas las funciones y los javascript’s y todos los controles con cuales tiene que funcionar me da el siguiente error:

    1.- que cuando ingresa al formulario donde esta implementado lo tu histes es como se metiera en un bucle haciendo postback n-veces por unos segundos (mas o menos unos 25 seg).

  5. Bueno antes que nada gracias al comentario anterior de roxana y en cuanto a kradlewish, la verdad que no tengo idea porque pasa. A simple vista se me ocurre que puede estar entrando indefinidas veces por esta linea:
    __doPostBack(‘linkPostBack’,”) eso hace postbacks desde javascript.
    Fijate si podes poner algo de codigo para poder darte una mano.
    Saludos!

  6. Hola.
    Soy principiante en aspnet y queria preguntarte la capeta ImagenesCarpeta\ es simplemente una carpeta creada en el sitio web desde la raiz?????? mi problema es que pareciera que se carga pero no muestra nada en la imagen

  7. Amigo gracias por el articulo… segui probandolo y ya me funciono, ahora voy a tratar de adaptarlo a c# y aumentar funcionalidad de acuerdo a lo que necesito…pero este articulo fue realmente valioso para mi…mil gracias….Espero encontrar mas articulos tuyos ..son muy buenos

  8. Hola amigo espero que estes muy bien

    Disculpa la molestia pero no se si te sea posible poner el codigo en c# o solo CargarFotografia(), yo lo cambie a c# pero no me funciona…parece que se cargara las imagenes a la carpeta pero en realidad no se carga nada.

    De antemano gracias por tu ayuda

  9. alguien me puede ayudar estoy trabajando con Access, he hecho una base de datos, solo me queda agregar la fotografia de las personas, he realizado un modulo como lo señalo lineas abajo pero cuando realizo insertar imagen, me envia al modulo getFileName,con un mensaje error de compilacion-no se hafinido la variable. Y no abre las imagenes que puedo hacer, gracias :

    Option Compare Database
    Option Explicit
    Dim path As String

    Private Sub AddPicture_Click()
    ‘ Utilice el cuadro de diálogo Abrir archivo de Office para obtener el nombre de un archivo que vaya a utilizar
    ‘ como la imagen de un empleado.
    getFileName
    End Sub

    Private Sub Form_RecordExit(Cancel As Integer)
    ‘ Oculte la etiqueta de mensajes de error para minimizar el parpadeo durante la exploración
    ‘ entre registros.
    ErrorMsg.Visible = False
    End Sub

    Private Sub RemovePicture_Click()
    ‘ Borre el nombre de archivo para el registro de empleado y muestre la
    ‘ etiqueta de mensajes de error.
    Me![ImagePath] = “”
    hideImageFrame
    ErrorMsg.Visible = True
    End Sub

    Private Sub Form_AfterUpdate()
    ‘ Consulte de nuevo el cuadro combinado ReportsTo una vez se haya modificado un registro.
    ‘ A continuación, muestre la etiqueta de mensajes de error si no existe ningún nombre de archivo para
    ‘ el registro de empleado o muestre la imagen si existe un nombre
    ‘ de archivo.
    Me![Jefe].Requery
    On Error Resume Next
    showErrorMessage
    showImageFrame
    If (IsRelative(Me!ImagePath) = True) Then
    Me![ImageFrame].Picture = path & Me![ImagePath]
    Else
    Me![ImageFrame].Picture = Me![ImagePath]
    End If
    End Sub

    Private Sub ImagePath_AfterUpdate()
    ‘ Una vez seleccionada una imagen para el empleado, muéstrela.
    On Error Resume Next
    showErrorMessage
    showImageFrame
    If (IsRelative(Me!ImagePath) = True) Then
    Me![ImageFrame].Picture = path & Me![ImagePath]
    Else
    Me![ImageFrame].Picture = Me![ImagePath]
    End If
    End Sub
    Private Sub Form_Current()
    ‘ Muestre la imagen para el registro actual del empleado, siempre que la imagen
    ‘ exista. Si el nombre de archivo no existe o está en blanco para
    ‘ el empleado actual, configure el título de la etiqueta de mensajes de error en el
    ‘ mensaje correspondiente.
    Dim res As Boolean
    Dim fName As String

    path = CurrentProject.path
    On Error Resume Next
    ErrorMsg.Visible = False
    If Not IsNull(Me![Foto]) Then
    res = IsRelative(Me![Foto])
    fName = Me![ImagePath]
    If (res = True) Then
    fName = path & “\” & fName
    End If

    Me![ImageFrame].Picture = fName
    showImageFrame
    Me.PaintPalette = Me![ImageFrame].ObjectPalette
    If (Me![ImageFrame].Picture fName) Then
    hideImageFrame
    ErrorMsg.Caption = “No se encuentra la imagen”
    ErrorMsg.Visible = True
    End If
    Else
    hideImageFrame
    ErrorMsg.Caption = “Haga Click en Añadir/Cambiar para añadir imagen”
    ErrorMsg.Visible = True
    End If

    End Sub

    Sub getFileName()
    ‘ Muestre el cuadro de diálogo Abrir archivo de Office para elegir un nombre de archivo
    ‘ para el registro del empleado actual. Si el usuario selecciona un archivo,
    ‘ muéstrelo en el control de imagen.
    Dim fileName As String
    Dim result As Integer
    With Application.FileDialog(msoFileDialogFilePicker)
    .Title = “Seleccione la imagen del empleado”
    .Filters.Add “All Files”, “*.*”
    .Filters.Add “JPEGs”, “*.jpg”
    .Filters.Add “Bitmaps”, “*.bmp”
    .FilterIndex = 3
    .AllowMultiSelect = False
    .InitialFileName = CurrentProject.path
    result = .Show
    If (result 0) Then
    fileName = Trim(.SelectedItems.Item(1))
    Me![ImagePath].Visible = True
    Me![ImagePath].SetFocus
    Me![ImagePath].Text = fileName
    Me![Nombre].SetFocus
    Me![ImagePath].Visible = False
    End If
    End With
    End Sub

    Sub showErrorMessage()
    ‘ Muestre la etiqueta de mensajes de error si el archivo de imagen no se encuentra disponible.
    If Not IsNull(Me![Foto]) Then
    ErrorMsg.Visible = False
    Else
    ErrorMsg.Visible = True
    End If
    End Sub

    Function IsRelative(fName As String) As Boolean
    ‘ Devuelva el valor falso si el nombre de archivo contiene una unidad o ruta de acceso UNC
    IsRelative = (InStr(1, fName, “:”) = 0) And (InStr(1, fName, “\\”) = 0)
    End Function

    Sub hideImageFrame()
    ‘ Oculte el control de imagen
    Me![ImageFrame].Visible = False
    End Sub

    Sub showImageFrame()
    ‘ Muestre el control de imagen
    Me![ImageFrame].Visible = True
    End Sub

  10. hola disculpa..por molestar pero he tomado tu codigo…y en el momento de cargar me pararece un error de sesion
    queria saber donde estas poniendo la conwexion a la bd y donde estan los campos de la tabla en donde lo esta guardando .
    soy nueva en esto asi ke agradeseria tu ayuda

  11. hola….

    soy nuevo en el tema, me gustaría que me explicasen como subir la imagen para guardarla en una base de datos que se crea dentro del mismo visual, estoy tratando de hacerla con visual studio 2010. quiero que un usuario busque su imagen, pueda subirla y visualizarla cuando se haya registrado.

    gracias

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s