2011-01-07 3 views
5

У меня есть обработанные текстовые поля и другие элементы, но я хочу получить растровое изображение, чтобы сохранить его на диске. Мне нужно сделать это прямо из WatiN, если это возможно.Как получить растровое изображение элемента изображения WatiN?

Как я могу это сделать?

ответ

5

Я не думаю, что вы можете получить двоичную информацию непосредственно у WatiN. Однако у вас есть метод Image.Uri, который дает вам URI изображения. Таким образом, его легко загрузить с 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); 
     } 
    } 
} 

Надеется, что это помогает

+2

Да я мог бы использовать это, но с каждым запросить изображение меняется ... PHP код создает новый образ на каждом запросе, так что мне нужно точно как в WatiN. Может быть, привязка к IHtmlDocument или что-то еще? –

+0

@Baptiste Pernet - Спасибо за ответ, он решил мою проблему. Еще раз спасибо. :) – Bibhu

7

У меня были аналогичной проблема некоторое время назад. Watin не может сделать это напрямую, но он предоставляет объекты mshtml, необходимые для получения некоторых результатов.

В то время мой код был в значительной степени, как это:

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 
       } 
      } 
     } 

    } 
} 

Этот маленький хак, в основном, пытается скопировать изображение в буфер обмена. Однако у меня было несколько проблем, из-за которых он работал правильно, и в итоге удалось сделать снимок области вокруг изображения и сохранить его на диске.

Хотя это может быть очень полезно, это может указывать вам в некоторых направлениях ..

+0

Thx, я попробую, когда вернусь из отпуска и, возможно, опубликую свои результаты. –

+1

есть исключение безопасности в IE. любая идея, как это решить? спасибо – kakopappa

+0

Это не сработает для Firefox, есть ли у вас решение для firefox? CaptureWebPageToFile также генерирует черное изображение. –

0

У меня была такая проблема, и я не мог решить. PHP генерировал новые изображения все время, поэтому я использовал метод 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; 
    } 

Это метод, который я использую для генерируемых php изображений. Это связано с моим собственным WebBrowserClass, который расширяет элемент управления веб-браузером.

(так "это" = WebBrowser)

Но мы должны импортировать интерфейс IHTMLElementRender2, чтобы использовать этот метод.

[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); 
    }; 

Я нашел этот метод в сети около 1 года назад, поэтому, если вы его ищете, вы можете найти более подробную информацию.

Iwan

+0

Можно даже захватить все содержимое элемента div. Таким образом, он не только работает с элементами изображения. ;) – Iwan1993

+0

Кажется, для меня не работает - 'Element.style.width' is' null' :( –

+0

Зависит от вашего элемента. Возможно, вы можете протестировать его с помощью известного элемента «q» Google. – Iwan1993

1

Некоторое время назад мне нужно извлечь данные изображения тоже, так что я пришел с этим решением:

создать скрытое поле и холст внутри страницы, используя

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

превратить его на base64 с использованием javascript и получения его значения

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();"); 

затем получение кодифицированного значения

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); 
       } 

Надеется, что это помогает :)

Смежные вопросы