Как получить растровое изображение элемента изображения WatiN? - PullRequest
6 голосов
/ 07 января 2011

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

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

Ответы [ 5 ]

7 голосов
/ 12 января 2011

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

    }
}

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

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

5 голосов
/ 07 января 2011

Я не думаю, что вы можете получить двоичную информацию напрямую от 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 голосов
/ 12 ноября 2013

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

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

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

Надеюсь, это поможет:)

2 голосов
/ 02 января 2012
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.

(так "this" = 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);
    };

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

Iwan

0 голосов
/ 03 октября 2011

У меня была такая проблема, и я не мог ее решить.PHP постоянно генерировал новые изображения, поэтому я использовал метод CaptureWebPageToFile().

...