Foro de elhacker.net

Programación => Scripting => Mensaje iniciado por: footer en 28 Julio 2017, 07:54 am



Título: Descargar imagen de una 'URI'
Publicado por: footer en 28 Julio 2017, 07:54 am
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 =
Código:
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
  1. Set objWinHttp = CreateObject("WinHttp.WinHttpRequest.5.1")
  2.  
  3. URL = "Url/imagen.jpg"  ' Aqui pondria mi url
  4. objWinHttp.open "GET", URL, False
  5. objWinHttp.send ""
  6.  
  7. SaveBinaryData "D:\somefolder\my.png",objWinHttp.responseBody
  8.  
  9. Function SaveBinaryData(FileName, Data)
  10.  
  11. ' adTypeText for binary = 1
  12. Const adTypeText = 1
  13. Const adSaveCreateOverWrite = 2
  14.  
  15. ' Create Stream object
  16. Dim BinaryStream
  17. Set BinaryStream = CreateObject("ADODB.Stream")
  18.  
  19. ' Specify stream type - we want To save Data/string data.
  20. BinaryStream.Type = adTypeText
  21.  
  22. ' Open the stream And write binary data To the object
  23. BinaryStream.Open
  24. BinaryStream.Write Data
  25.  
  26. ' Save binary data To disk
  27. BinaryStream.SaveToFile FileName, adSaveCreateOverWrite
  28.  
  29. End Function
  30.  


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 (http://foro.elhacker.net/reglas.htm)
-Engel Lex


Título: Re: Descargar imagen de una 'URI'
Publicado por: engel lex en 28 Julio 2017, 08:08 am
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 (https://es.wikipedia.org/wiki/Base64)


Título: Re: Descargar imagen de una 'URI'
Publicado por: footer en 28 Julio 2017, 09:02 am
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...  ;-)



Título: Re: Descargar imagen de una 'URI'
Publicado por: engel lex en 28 Julio 2017, 09:07 am
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


Título: Re: Descargar imagen de una 'URI'
Publicado por: 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)


Título: Re: Descargar imagen de una 'URI'
Publicado por: engel lex en 28 Julio 2017, 09:21 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


Título: Re: Descargar imagen de una 'URI'
Publicado por: Eleкtro en 28 Julio 2017, 14:10 pm
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...



Asi 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
  1. Imports System.Drawing
  2. Imports System.IO
  3.  
  4. Dim content As String = "data:image/png;base64,"
  5. Dim base64 As String = content & "R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw=="
  6. Dim raw As Byte() = Convert.FromBase64String(base64.Replace(content, ""))
  7.  
  8. Using ms As New MemoryStream(raw, writable:=False),
  9.      img As Image = Image.FromStream(ms, useEmbeddedColorManagement:=True, validateImageData:=True)
  10.  
  11.    img.Save("C:\file.png", img.RawFormat)
  12. End Using

C#:
Código
  1. using System.Drawing;
  2. using System.IO;
  3.  
  4. string content = "data:image/png;base64,";
  5. string base64 = content + "R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==";
  6. byte[] raw = Convert.FromBase64String(base64.Replace(content, ""));
  7.  
  8. using (MemoryStream ms = new MemoryStream(raw, writable: false)) {
  9. using (Image img = Image.FromStream(ms, useEmbeddedColorManagement: true, validateImageData: true)) {
  10. img.Save(@"C:\file.png", img.RawFormat);
  11. }
  12. }

PowerShell:
Código
  1. [void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
  2.  
  3. [String]$content = "data:image/png;base64,"
  4. [String]$base64  = $content + "R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw=="
  5. [Byte[]]$raw     = [Convert]::FromBase64String($base64.Replace($content, ""))
  6.  
  7. [IO.MemoryStream]$ms = New-Object IO.MemoryStream @($raw, $false)
  8. [Drawing.Image]$img = [Drawing.Image]::FromStream($ms, $true, $true)
  9.  
  10. $img.Save("C:\file.png", $img.RawFormat)
  11.  
  12. Exit(0)

Saludos!


Título: Re: Descargar imagen de una 'URI'
Publicado por: ivancea96 en 29 Julio 2017, 14:38 pm
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
  1. <img src="aqui la URI" />
Y abras el archivo con el navegador.


Título: Re: Descargar imagen de una 'URI'
Publicado por: footer en 29 Julio 2017, 15:16 pm
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.


Título: Re: Descargar imagen de una 'URI'
Publicado por: Eleкtro en 29 Julio 2017, 15:56 pm
Ahora 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...

  • https://www.autoitscript.com/autoit3/docs/functions/Run.htm
  • https://www.autoitscript.com/autoit3/docs/functions/StdoutRead.htm

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:
  • https://github.com/J2TeaM/AutoIt-Imgur-UDF/blob/master/include/Base64.au3
  • https://www.autoitscript.com/forum/topic/107501-simple-base64-encoderdecoder/

...Probablemente aquí puedas encontrar más utilidades:
  • http://lmgtfy.com/?q=autoit+base64



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!


Título: Re: Descargar imagen de una 'URI'
Publicado por: footer en 30 Julio 2017, 07:27 am
Hola todos de nuevo yo xD si recuerdan, lo ultimo que queria hacer era decirle a autoit que envie comandos a la consola CMD de windows para ejecutar condigo de java ya compilado asi que hice un codigo que hace eso, envia comandos y captura la respuesta por medio de la cmd, si no me equivoco eso es una de las cosas que me sugirio elektro.
Gracias Elektro (Y).

Para hacer mi codigo me base en este post:

https://foro.elhacker.net/scripting/funcion_autoit_cmd_prompt-t404085.0.html

Con ese post el trabajo ya estaba hecho  xD solamente lo que hice fue hacer una "version" en castellano con comentarios y hacer  que la funcion nos dejara establecer el timeoutlimit en milisegundos y que la funcion retorne el resultado en lugar de sobreescribir una avariable, de esa manera controlar las respuestas por separado.
Pero el funcionamiento del codigo es elmismo y se lo debo al autor de ese post llamado "79137913". Si quieren verlo:

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

Asi que para ejecutar codigo java haria asi:


iniciarCMD(); Iniciamos consola cmd.

$comando1 = ejecutarComando("cd RutaArchivoJava",1000); le decimos al prompt q se hubique en la dir del archivo a ejecutar
$comando2 = ejecutarComando("java NombreJava",1000); le decimos que ejecute ese archivo por medio del comando 'java'

;se muestran resultado de esos comandos en consola
ConsoleWrite($comando1)
ConsoleWrite($comando2)

Mi siguiente problema en mi lista seria: como enviarle la src de la imagen a java, se supone que el codigo java debe recibir un String cifrado para descifrar y generar la imagen, dicho String lo obtiene autoit y autoit debe enviarselo a java.

Flujo de src:
encriptacion -----> autoit3 ----> java
                                        
Estaba pensando que autoit3 puede guardar la encriptacion en un archivo .txt y luego de eso ejecutar codigo java desde consola cmd, y java buscar la encriptacion en el mismo txt. Pero como siempre me gusta escuchar opiniones y seran agradecidas. Si hago eso el flujo de la encriptacion quedaria asi:

encriptacion -----> autoit3 ---------> archivo.txt -----> java

Saludos.

PD: elektro acerca del link que me enviaste sobre descifrar base64 directamente en autoit es algo que voy a tratar de hacer despues que logre lo dicho anteriormente, es cierto que deberia haber empezado por ahi pero ya estoy en este metodo jeje si logro que trabaje intentare descifrar y guardar la imagen directo con autoit3 sin java.



Edito:

Hice un codigo en java que descifra una imagen de acuerdo a una cadena cifrada contenida en un txt, y luego guarda la imagen. Subido a google drive.

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

Saludos.