How do I get a bitmap of the WatiN image element?

旧街凉风 提交于 2019-11-27 18:37:12

问题


I have some textfields processed and other elements, but I want to get the bitmap so I can save it somewhere on disk. I need to do it directly from WatiN if this is possible.

How can I do this?


回答1:


I had a similar problem some time ago. Watin can't do this directly but it exposes the mshtml objects needed to get some results.

At the time my code was pretty much like this:

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

    }
}

This little hack, basically, tries to copy the image to the clipboard. However I had a couple of problems making it work properly and ended up snapshoting the region around the image and saving it to disk.

Although this may not be very helpful it may point you in some directions..




回答2:


I don't think you can get the binary information directly from WatiN. However you have Image.Uri method give you the URI of the image. So then it is easy to download it wih http request.

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

Hope this helps




回答3:


A while ago I needed to extract image data too so I came with this solution:

Create an hidden field and a canvas inside the page using

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

transform it to base64 using javascript and retrieving its value

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

then retrieving the codified value

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

Hope it helps :)




回答4:


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

That's the Method i use for php generated images. It's implimented in my own WebBrowserClass, which extends the webbrowser control.

(so "this" = WebBrowser)

But we have to import the IHTMLElementRender2 interface, to use the method.

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

I found this method in web, about 1 year ago, so if you search for it you might find more information.

Iwan




回答5:


I had such problem, and I could not solve it. PHP generated new images all the time so I used the CaptureWebPageToFile() method.



来源:https://stackoverflow.com/questions/4627197/how-do-i-get-a-bitmap-of-the-watin-image-element

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!