Descargar imagen de una 'URI'

Iniciado por footer, 28 Julio 2017, 07:54 AM

0 Miembros y 1 Visitante están viendo este tema.

footer

Hola todos, desde hace ya unos dias estoy "desarrollando" un proyecto en autoit3 y quede varado en un problema :/ y es el siguiente:

yo tengo una URI de este tipo:

$URI =
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPoAAABkCAYAAACvgC0O

contenido truncado, no es necesario ponerlo todo



Disculpen por la longitud de la URL es que es asi de larga, si lo copian en el navegador les abrira una imagen que es la que quiero descargar.


Si ya se, es una url bastante rara, investigando encontre que se les llaman "uri", pero se las consideran dentro de la categoria "url" en fin, esta url abre una imagen en el navegador, yo queria saber como puedo descargarla.


He intentado con un codigo vbs que encontre por ahi, el codigo funciona con url "comunes" descargando la img pero cuando le pongo esta url me devuelve error diciendome: "La url no utiliza ninguno de los protocolos conocidos". Asi que les pido por favor si alguien me da una mano, no importa el lenguaje ya que aprender un poco no me molesta solo quiero que me ayuden a solucionarlo. El codigo vbs es este:


Codigo vbs:


Código (vb) [Seleccionar]
Set objWinHttp = CreateObject("WinHttp.WinHttpRequest.5.1")

URL = "Url/imagen.jpg"  ' Aqui pondria mi url
objWinHttp.open "GET", URL, False
objWinHttp.send ""

SaveBinaryData "D:\somefolder\my.png",objWinHttp.responseBody

Function SaveBinaryData(FileName, Data)

' adTypeText for binary = 1
Const adTypeText = 1
Const adSaveCreateOverWrite = 2

' Create Stream object
Dim BinaryStream
Set BinaryStream = CreateObject("ADODB.Stream")

' Specify stream type - we want To save Data/string data.
BinaryStream.Type = adTypeText

' Open the stream And write binary data To the object
BinaryStream.Open
BinaryStream.Write Data

' Save binary data To disk
BinaryStream.SaveToFile FileName, adSaveCreateOverWrite

End Function



El codigo anterior funciona con url de imagenes "comunes" pero si le pongo la url que quiero deja exactemente este error:

Linea: 4
Caracter: 4
error: "La dirección URL no usa un protocolo reconocido"
Codigo: 80072EE6
Origen: WinHttp.WinHttpRequest


Gracias desde ya y saludos.





· Los códigos deben ir en etiquetas GeSHi
>aquí las reglas del foro
-Engel Lex

engel lex

#1
XD te estás dando en la cabeza con una piera... eso no es un uri o url, no es un enlace...

la cabecera dice lo que es "data:image/png;base64"

es la data de una imagen png en base64...  es decir esa cadena de texto es la imagen... por eso es tan largo! XD

necesitas convertirlo de base64 a binario para poder guardarlo...  esto no es complicado pero sin conocimientos claros para trabajar en conversiones a byte puede ser muy pesado

https://es.wikipedia.org/wiki/Base64
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

footer

Gracias por la respuesta jeje todavia estoy en lo mismo xD

y pude encontrar una forma de descargarla pero tiene inconvenientes:
1_ descarga un archivo sin formato (pero lo bueno es que si le agrego '.jpg' al final puedo ver la img en mi pc :D

2_ para descargar debo usar codigo javascript, modificando una parte de la src puedo hacer que se descargue en lugar de mostrar la img de esta forma:

Reemplazar "image/png" (cadena que esta en la src) por esta cadena "application/octet-stream"
El problema es que se descarga un archivo que tiene el icono de windows (banderas de 4 colores) y tiene como si fuera un disco duro atras, no tiene formato o al menos no le encuentro pero al agregarle formato lo abre el visualizador de imagenes sin problemas.


Igualmente estoy muy interesado en lo que dijiste, estuve leyendo es como una codificacion. Si tu tienes conocimientos del asunto, podrias indicarme por donde empezar con eso de Base64?. Me parece mas interesante y tal vez podria ahorrarme algunos dolores de cabeza...  ;-)


engel lex

te deje el link de la wiki, leelo y si tienes alguna duda al respecto avisa...

el icono que te muestra porque porque windows identifica los archivos por su extensión... por cierto, no es jpg, es png
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

footer

Una ultima duda antes que nada, quieres decir que si tomo la url, la decodifico, luego guardo esa decodificacion en un bloc de notas y lo guardo ".png" deberia abrir la imagen?

Gracias por la info (Y)

engel lex

Cita de: footer en 28 Julio 2017, 09:16 AM
Una ultima duda antes que nada, quieres decir que si tomo la url, la decodifico, luego guardo esa decodificacion en un bloc de notas y lo guardo ".png" deberia abrir la imagen?

Gracias por la info (Y)

no... en un bloc de notas no porque la decodificación es binaria y lo caracteres imprimibles son limitados y reinterpretados por bloc de notas...

sin embargo si lo lees y haces la respectiva conversión de bytes y lo guardas en binario, si, se vería

la wiki tiene toda la explicación necesaria para decodificar
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

Eleкtro

#6
Te han intentado aclarar repetidamente que eso no es una URL, sino la imagen (de forma literal, eso es la imagen), son los bytes de la imagen codificados en el formato BASE-64. ¿Lo entiendes?. Te han pasado un artículo de la Wikipedia, y dices que aprender no te molesta, pues deberías leerlo...




Cita de: footer en 28 Julio 2017, 07:54 AMAsi que les pido por favor si alguien me da una mano, no importa el lenguaje

Ejemplos de como decodificar una cadena de texto BASE-64:

VB.NET:
Código (vbnet) [Seleccionar]
Imports System.Drawing
Imports System.IO

Dim content As String = "data:image/png;base64,"
Dim base64 As String = content & "R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw=="
Dim raw As Byte() = Convert.FromBase64String(base64.Replace(content, ""))

Using ms As New MemoryStream(raw, writable:=False),
     img As Image = Image.FromStream(ms, useEmbeddedColorManagement:=True, validateImageData:=True)

   img.Save("C:\file.png", img.RawFormat)
End Using


C#:
Código (csharp) [Seleccionar]
using System.Drawing;
using System.IO;

string content = "data:image/png;base64,";
string base64 = content + "R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==";
byte[] raw = Convert.FromBase64String(base64.Replace(content, ""));

using (MemoryStream ms = new MemoryStream(raw, writable: false)) {
using (Image img = Image.FromStream(ms, useEmbeddedColorManagement: true, validateImageData: true)) {
img.Save(@"C:\file.png", img.RawFormat);
}
}


PowerShell:
Código (csharp) [Seleccionar]
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

[String]$content = "data:image/png;base64,"
[String]$base64  = $content + "R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw=="
[Byte[]]$raw     = [Convert]::FromBase64String($base64.Replace($content, ""))

[IO.MemoryStream]$ms = New-Object IO.MemoryStream @($raw, $false)
[Drawing.Image]$img = [Drawing.Image]::FromStream($ms, $true, $true)

$img.Save("C:\file.png", $img.RawFormat)

Exit(0)


Saludos!








ivancea96

Si quieres ver la imagen y poder descargarla rápidamente, basta que crees un archivo html "abc.html", pongas dentro el código:
Código (html5) [Seleccionar]
<img src="aqui la URI" />
Y abras el archivo con el navegador.

footer

#8
Hola gracias por las respuestas, pero encontre una solucion en java, gracias a las clases Base64.Encoder y Base64.Decoder pude solucionar el problema, hice un codigo que toma una imagen, la cifra, luego la descifra y la guarda con otro nombre.

Aqui esta el link de descarga subido a google drive por si alguien lo quiere:

https://drive.google.com/open?id=0B1i-JNEuRD1zTUJjU2VMLXhJT28

Y quiero aclarar algo, yo nunca dije "no me cuesta aprender" solamente dije "no me molesta aprender" jaja y con eso de "no me importa el lenguaje" me referia a que la teoria es la misma sea cual sea el lenguaje. Ahora me pregunto... como hago para que autoit se comunique con java?? podria ser por medio de la consola de windows? enviando "java nombre"? si alguien tiene una idea agradeceria la opinion. Saludos.

PD:Eleкtro estuve viendo tus codigos y aunque no los manejo para nada me parece que en el de VB.NET podrias omitir definir la primer variable ya que despues la dejas sin nada dentro podrias haber hecho directamente:


Dim base64 As String ="R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw=="
Dim raw As Byte() = Convert.FromBase64String(base64)

Si estoy equivocado corrigeme por favor.

Eleкtro

#9
Cita de: footer en 29 Julio 2017, 15:16 PMAhora me pregunto... como hago para que autoit se comunique con java?? podria ser por medio de la consola de windows? enviando "java nombre"?

Sería una posibilidad, por supuesto, puedes desarrolllar una aplicación de consola en Java y desde AutoIt la puedes iniciar y capturar la respuesta/código de salida del programa en el bufer de salida StdOut (me refiero, en caso de que lo necesites). Puedes hacer lo mismo con una aplicación .NET (VB.NET, C#, F#, VC++), un script JScript, o un script PowerShell, etc...


De todas formas en realidad yo no creo que necesites recurrir a lenguajes adicionales... ya que es de suponer que en el propio AutoIt debas poder decodificar un string BASE64:

...Probablemente aquí puedas encontrar más utilidades:




Cita de: footer en 29 Julio 2017, 15:16 PM
PD:Eleкtro estuve viendo tus codigos y aunque no los manejo para nada me parece que en el de VB.NET podrias omitir definir la primer variable ya que despues la dejas sin nada dentro podrias haber hecho directamente:

Dim base64 As String ="R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw=="
Dim raw As Byte() = Convert.FromBase64String(base64)

Si estoy equivocado corrigeme por favor.

No, no te equivocas en absoluto, pero tiene una explicación lógica: la variable "content" tan solo la declaré para denotar o diferenciar que el contenido no forma parte de la codificación BASE64, o dicho de otra forma: lo escribí como mera formalidad para evitar generarte posibles confusiones puesto que al principio parecias un poco "perdido" con el tema de la codificación BASE64. Es por ese motivo que en los tres códigos lo primero que hago es declarar la variable content ("data:image/png;base64,") y la concateno con el string BASE64 para luego seguidamente borrar lo que he concatenado ("data:image/png;base64,"), es evidente que hacer eso en un escenario real sería de lo más absurdo (sin sentido ninguno), pero en ese código tan solo era un ejemplo demostrativo para denotar las diferencias y tratar de no despistarte.

Me alegra saber que hayas analizado los códigos que se te ofrecieron, que te hayas dado cuenta de eso por ti mismo, y que lo hayas cuestionado.

Saludos!