jueves, 19 de agosto de 2010

ASP.NET – Recuperar imagen desde url

bebe_borrachin
No señores, este blog no ha cambiado de temática… jeje es sólo una imagen que muestro para darle alegría al post.
Empecemos. La pregunta es:
Cómo puedo guardar en una carpeta de mi servidor, una imagen que está mostrándose en una página web?
obviamente de manera automatizada desde una página aspx no?
Veamos que se presentan dos posibles repositorios para guardar la imagen:
+ Guardar la imagen en una carpeta de mi servidor.
+ Guardar la imagen directamente en la base de datos.

1.- Guardar la imagen en una carpeta de mi servidor: añadan una carpeta llamada downloads en la raiz de su aplicación web y luego usaría este código:
Sub SaveImageToFolder(ByVal ImageUrl As String, ByVal NewImageName As String)
Dim Folder As String = Server.MapPath("~/downloads/") & NewImageName

Dim client As New Net.WebClient()
client.DownloadFile(ImageUrl, Folder)

End Sub

2.- Guardar la imagen en la base de datos: Esto requiere un paso más, porque primero debo convertir la imagen a un array de bytes… y lo hago con esta función:
Private Function GetImage(ByVal ImageUrl As String) As Byte()
Dim bytes As Byte() = Nothing
Dim req As Net.HttpWebRequest = DirectCast(Net.WebRequest.Create(ImageUrl), Net.HttpWebRequest)
Dim resp As Net.WebResponse = req.GetResponse()

Dim ImageStream As IO.Stream = resp.GetResponseStream()
Using br As New IO.BinaryReader(ImageStream)
If ImageStream.Length > 0 Then
bytes = br.ReadBytes(ImageStream.Length)
br.Close()
End If
End Using
resp.Close()

Return bytes

End Function

Para guardar la imagen en la base de datos se supone que tengo una tabla en la base de datos, la cual tiene un campo de tipo IMAGE llamado my_image para guardar el arreglo de bytes, y adicionalmente añadiríamos un campo llamado FileName para el nombre de la imagen, y luego guardaríamos la imagen.

Ahora, este es el código completo:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

Dim ImageUrl As String = "http://www.gildus.com.ar/news/wp-content/uploads/2008/12/bebe_borrachin.jpg"
        Dim ImageExt() As String = ImageUrl.Split("/")
Dim NewImageName As String = "MyImage." & ImageExt(ImageExt.GetUpperBound(0)).Split(".")(ImageExt(ImageExt.GetUpperBound(0)).Split(".").GetUpperBound(0))

'guardar a carpeta del servidor
SaveImageToFolder(ImageUrl, NewImageName)

'guardar a base de datos
SaveImageToDatabase(ImageUrl, NewImageName)

End Sub

Public Sub SaveImageToDatabase(ByVal ImageUrl As String, ByVal NewImageName As String)
Dim img() As Byte = GetImage(ImageUrl)

Dim cnn As New SqlClient.SqlConnection("server=your_server;database=yor_database;uid=your_user;pwd=your_password")
Dim sql As String = "INSERT INTO MY_TABLE(FileName, my_image) VALUES(@filename, @my_image) SELECT SCOPE_IDENTITY()"

        cnn.Open()
Dim cmd As SqlClient.SqlCommand = New SqlClient.SqlCommand(sql, cnn)
cmd.Parameters.AddWithValue("@filename", NewImageName)
cmd.Parameters.AddWithValue("@my_image", img)

If Convert.ToInt32(cmd.ExecuteScalar()) = 0 Then
'mensaje de error
End If

End Sub

Private Function GetImage(ByVal ImageUrl As String) As Byte()
Dim bytes As Byte() = Nothing
Dim req As Net.HttpWebRequest = DirectCast(Net.WebRequest.Create(ImageUrl), Net.HttpWebRequest)
Dim resp As Net.WebResponse = req.GetResponse()

Dim ImageStream As IO.Stream = resp.GetResponseStream()
Using br As New IO.BinaryReader(ImageStream)
If ImageStream.Length > 0 Then
bytes = br.ReadBytes(ImageStream.Length)
br.Close()
End If
End Using
resp.Close()

Return bytes

End Function

Sub SaveImageToFolder(ByVal ImageUrl As String, ByVal NewImageName As String)
Dim Folder As String = Server.MapPath("~/downloads/") & NewImageName

Dim client As New Net.WebClient()
client.DownloadFile(ImageUrl, Folder)

End Sub

Espero que les sea de utilidad ;)

3 comentarios:

Anónimo dijo...

Una consulta amigo, yo tengo guardas varias imagenes en una base de datos mysql, lo que quiero hacer es poder descargar varias de esas imagenes... hasta el momento solo he logrado dercargar una ala ves...

tenia pensado en guardar esas imagenes en el servidor como archivo y luego comprimirlas y descargarlas... no se si alla otra opcion!!

Segundo Serrano dijo...

hola Hector Medina,

la solución que propones es buena y es lo más común.

Saludos

Unknown dijo...

Es lo que busco pero me muestra un error en
If ImageStream.Length > 0 Then

Esta secuencia no es compatible con operaciones de búsqueda.
ojala puedas orientarme, gracias