2011-01-07 6 views

Respuesta

5

No creo que pueda obtener la información binaria directamente de WatiN. Sin embargo, tiene el método Image.Uri que le proporciona el URI de la imagen. Entonces, es fácil descargarlo con solicitud HTTP.

using (Browser browser = new IE("http://www.sp4ce.net/computer/2011/01/06/how-to-use-WatiN-with-NUnit.en.html")) 
{ 
    Image image = browser.Images[0]; 
    Console.Write(image.Uri); 

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(image.Uri); 
    WebResponse response = request.GetResponse(); 
    using (Stream stream = response.GetResponseStream()) 
    using (FileStream fs = File.OpenWrite(@"c:\foo.png")) 
    { 
     byte[] bytes = new byte[1024]; 
     int count; 
     while((count = stream.Read(bytes, 0, bytes.Length))!=0) 
     { 
     fs.Write(bytes, 0, count); 
     } 
    } 
} 

espero que esto ayude

+2

Sí que podría utilizar esto, pero con cada petición la imagen está cambiando ... código PHP genera nueva imagen en cada petición, por lo que necesitan exactamente el lo mismo que en WatiN. ¿Tal vez algún enlace a IHtmlDocument o algo así? –

+0

@Baptiste Pernet - Gracias por la respuesta que resolvió mi problema. Gracias una vez más. :) – Bibhu

7

que tenía un problema similar hace algún tiempo. Watin no puede hacer esto directamente, pero expone los objetos mshtml necesarios para obtener algunos resultados.

En el momento mi código era más o menos así:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using WatiN.Core; 
using WatiN.Core.Native.InternetExplorer; 
using mshtml; 
using System.Windows.Forms; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     [STAThread] 
     static void Main(string[] args) 
     { 
      Browser browser = new IE("http://www.google.com"); 
      IEElement banner = browser.Images[0].NativeElement as IEElement; 

      IHTMLElement bannerHtmlElem = banner.AsHtmlElement; 
      IEElement bodyNative = browser.Body.NativeElement as IEElement; 
      mshtml.IHTMLElement2 bodyHtmlElem = (mshtml.IHTMLElement2)bodyNative.AsHtmlElement; 
      mshtml.IHTMLControlRange controlRange = (mshtml.IHTMLControlRange)bodyHtmlElem.createControlRange(); 

      controlRange.add((mshtml.IHTMLControlElement)bannerHtmlElem); 
      controlRange.execCommand("Copy", false, System.Reflection.Missing.Value); 
      controlRange.remove(0); 

      if (Clipboard.GetDataObject() != null) 
      { 
       IDataObject data = Clipboard.GetDataObject(); 
       if (data.GetDataPresent(DataFormats.Bitmap)) 
       { 
        System.Drawing.Image image = (System.Drawing.Image)data.GetData(DataFormats.Bitmap, true); 
        // do something here 
       } 
      } 
     } 

    } 
} 

Este pequeño programa, básicamente, trata de copiar la imagen al portapapeles. Sin embargo, tuve un par de problemas para que funcione correctamente y terminé capturando la región alrededor de la imagen y guardándola en el disco.

Aunque esto puede no ser muy útil que puede apuntar en algunas direcciones ..

+0

Thx, lo intentaré cuando regrese de vacaciones y tal vez publique mis resultados. –

+1

hay una excepción de seguridad en IE. ¿Alguna idea de como resolver esto? gracias – kakopappa

+0

No funcionará para Firefox, ¿tienes alguna solución para Firefox? CaptureWebPageToFile también genera imagen en negro –

0

tuve ese problema, y ​​no podía resolverlo. PHP generó nuevas imágenes todo el tiempo, así que usé el método CaptureWebPageToFile().

2
public Image GetImageFromElement(IHTMLElement Element) 
    { 
     int width = (int)Element.style.width; 
     int height = (int)Element.style.height; 
     IHTMLElementRender2 render = (IHTMLElementRender2)Element; 

     Bitmap screenCapture = new Bitmap(width, height); 
     Rectangle drawRectangle = new Rectangle(0, 0, width, height); 
     this.DrawToBitmap(screenCapture, drawRectangle); 
     Graphics graphics = Graphics.FromImage(screenCapture); 

     IntPtr graphicshdc = graphics.GetHdc(); 
     render.DrawToDC(graphicshdc); 
     graphics.ReleaseHdc(graphicshdc); 
     graphics.Dispose(); 

     return screenCapture as Image; 
    } 

Ese es el método que uso para las imágenes generadas por php. Está implícito en mi propio WebBrowserClass, que amplía el control del navegador web.

(por lo que "este" = WebBrowser)

pero tenemos que importar la interfaz IHTMLElementRender2, utilizar el método.

[Guid("3050f669-98b5-11cf-bb82-00aa00bdce0b"), 
     InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
     ComVisible(true), 
     ComImport] 
    interface IHTMLElementRender2 
    { 
     void DrawToDC([In] IntPtr hDC); 
     void SetDocumentPrinter([In, MarshalAs(UnmanagedType.BStr)] string bstrPrinterName, [In] IntPtr hDC); 
    }; 

me encontré con este método en la web, hace alrededor de 1 año, por lo que si usted busca para que usted puede encontrar más información.

Iwan

+0

Incluso es posible capturar todo el contenido de un elemento div. Por lo tanto, no solo funciona con elementos de imagen. ;) – Iwan1993

+0

Parece que no funciona para mí - 'Element.style.width' es' null' :( –

+0

Depende de tu elemento. Deberías probarlo usando el famoso elemento "q" de Google. – Iwan1993

1

Hace un tiempo que necesitaba para extraer datos de la imagen también, así que vinieron con esta solución:

crear un campo oculto y un lienzo en el interior de la página utilizando

ie.RunScript("document.body.innerHTML += \"<input type='hidden' id='hidden64'/>\";"); 
ie.RunScript("document.body.innerHTML += \"<canvas id='canv' width='150px' height='40px' ></canvas>\";"); 

transformarla a base64 usando javascript y recuperando su valor

ie.RunScript("var c = document.getElementById('canv');"); 
ie.RunScript("var ctx = c.getContext('2d');"); 
ie.RunScript("var img = document.getElementsByName('imgCaptcha')[0];"); 
ie.RunScript("ctx.drawImage(img, 10, 10);"); 
ie.RunScript("document.getElementById('hidden64').value=c.toDataURL();"); 

luego recuperar el valor codificado

string data = ie.Element(Find.ById("hidden64")).GetAttributeValue("value"); 

var base64Data = Regex.Match(data, @"data:image/(?<type>.+?),(?<data>.+)").Groups["data"].Value; 
       var binData = Convert.FromBase64String(base64Data); 
       Bitmap im; 
       using (var stream = new MemoryStream(binData)) 
       { 
        im = new Bitmap(stream); 
       } 

espero que ayude :)

Cuestiones relacionadas