paginas pagina page online imagenes full fireshot completa chrome capturar c# javascript .net highcharts

pagina - Captura de página web como imagen en c#, asegurando que los elementos renderizados de JavaScript sean visibles



full page screen capture (4)

Thread.Sleep simplemente suspenderá el hilo en el que se ejecuta su navegador web, ¿cómo espera que muestre algo cuando se suspende? :)

En cambio, debe permitir que el hilo procese el trabajo. Puede lograr esto con una combinación de Thread.Sleep(0) y Application.DoEvents() , con algo como lo siguiente:

DateTime finish = DateTime.Now.AddSeconds(3); while (DateTime.Now < finish) { Application.DoEvents(); Thread.Sleep(0); }

Estoy tratando de capturar la siguiente página usando el código c .net estándar. He buscado los diversos métodos de la gente, la mayoría de los cuales implican crear instancias de un objeto del navegador y usar un método de dibujar a mapa de bits. Sin embargo, ninguno de estos recoge el contenido del cuadro en esta página:

http://www.highcharts.com/demo/combo-dual-axes

Quizás el javascript no tenga tiempo para ejecutarse, pero agregar Thread.Sleep (x) no ha ayudado.

Este componente comercial lo captura correctamente, pero prefiero evitar una dependencia adicional en mi proyecto y pagar $ 150 cuando las otras soluciones son tan cercanas.

¿Alguien encuentra que su solución lo procesa correctamente?


Probablemente hayas probado IECapt . Creo que es el camino correcto a seguir. Creé una versión modificada y uso un timer lugar de Thread.Sleep captura su sitio como se esperaba.

------EDITAR------

Aquí está la fuente fea. Simplemente agregue una referencia a la Microsoft HTML Object Library .

Y este es el uso:

HtmlCapture capture = new HtmlCapture(@"c:/temp/myimg.png"); capture.HtmlImageCapture += new HtmlCapture.HtmlCaptureEvent(capture_HtmlImageCapture); capture.Create("http://www.highcharts.com/demo/combo-dual-axes"); void capture_HtmlImageCapture(object sender, Uri url) { this.Close(); }

Archivo1

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; namespace MyIECapt { public class HtmlCapture { private WebBrowser web; private Timer tready; private Rectangle screen; private Size? imgsize = null; //an event that triggers when the html document is captured public delegate void HtmlCaptureEvent(object sender, Uri url); public event HtmlCaptureEvent HtmlImageCapture; string fileName = ""; //class constructor public HtmlCapture(string fileName) { this.fileName = fileName; //initialise the webbrowser and the timer web = new WebBrowser(); tready = new Timer(); tready.Interval = 2000; screen = Screen.PrimaryScreen.Bounds; //set the webbrowser width and hight web.Width = 1024; //screen.Width; web.Height = 768; // screen.Height; //suppress script errors and hide scroll bars web.ScriptErrorsSuppressed = true; web.ScrollBarsEnabled = false; //attached events web.Navigating += new WebBrowserNavigatingEventHandler(web_Navigating); web.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(web_DocumentCompleted); tready.Tick += new EventHandler(tready_Tick); } public void Create(string url) { imgsize = null; web.Navigate(url); } public void Create(string url, Size imgsz) { this.imgsize = imgsz; web.Navigate(url); } void web_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { //start the timer tready.Start(); } void web_Navigating(object sender, WebBrowserNavigatingEventArgs e) { //stop the timer tready.Stop(); } void tready_Tick(object sender, EventArgs e) { try { //stop the timer tready.Stop(); mshtml.IHTMLDocument2 docs2 = (mshtml.IHTMLDocument2)web.Document.DomDocument; mshtml.IHTMLDocument3 docs3 = (mshtml.IHTMLDocument3)web.Document.DomDocument; mshtml.IHTMLElement2 body2 = (mshtml.IHTMLElement2)docs2.body; mshtml.IHTMLElement2 root2 = (mshtml.IHTMLElement2)docs3.documentElement; // Determine dimensions for the image; we could add minWidth here // to ensure that we get closer to the minimal width (the width // computed might be a few pixels less than what we want). int width = Math.Max(body2.scrollWidth, root2.scrollWidth); int height = Math.Max(root2.scrollHeight, body2.scrollHeight); //get the size of the document''s body Rectangle docRectangle = new Rectangle(0, 0, width, height); web.Width = docRectangle.Width; web.Height = docRectangle.Height; //if the imgsize is null, the size of the image will //be the same as the size of webbrowser object //otherwise set the image size to imgsize Rectangle imgRectangle; if (imgsize == null) imgRectangle = docRectangle; else imgRectangle = new Rectangle() { Location = new Point(0, 0), Size = imgsize.Value }; //create a bitmap object Bitmap bitmap = new Bitmap(imgRectangle.Width, imgRectangle.Height); //get the viewobject of the WebBrowser IViewObject ivo = web.Document.DomDocument as IViewObject; using (Graphics g = Graphics.FromImage(bitmap)) { //get the handle to the device context and draw IntPtr hdc = g.GetHdc(); ivo.Draw(1, -1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, hdc, ref imgRectangle, ref docRectangle, IntPtr.Zero, 0); g.ReleaseHdc(hdc); } //invoke the HtmlImageCapture event bitmap.Save(fileName); bitmap.Dispose(); } catch { //System.Diagnostics.Process.GetCurrentProcess().Kill(); } if(HtmlImageCapture!=null) HtmlImageCapture(this, web.Url); } } }

y File2

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.Runtime.InteropServices; namespace MyIECapt { [ComVisible(true), ComImport()] [GuidAttribute("0000010d-0000-0000-C000-000000000046")] [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] public interface IViewObject { [return: MarshalAs(UnmanagedType.I4)] [PreserveSig] int Draw( [MarshalAs(UnmanagedType.U4)] UInt32 dwDrawAspect, int lindex, IntPtr pvAspect, [In] IntPtr ptd, IntPtr hdcTargetDev, IntPtr hdcDraw, [MarshalAs(UnmanagedType.Struct)] ref Rectangle lprcBounds, [MarshalAs(UnmanagedType.Struct)] ref Rectangle lprcWBounds, IntPtr pfnContinue, [MarshalAs(UnmanagedType.U4)] UInt32 dwContinue); [PreserveSig] int GetColorSet([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [In] IntPtr ptd, IntPtr hicTargetDev, [Out] IntPtr ppColorSet); [PreserveSig] int Freeze([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [Out] IntPtr pdwFreeze); [PreserveSig] int Unfreeze([In, MarshalAs(UnmanagedType.U4)] int dwFreeze); } }


@LB, gracias por la ayuda!

Solo un FYI para cualquiera que desee ejecutarlo en una biblioteca de clases, WebBrowser necesita Single Single Threaded Apartment, así que haga algo como esto:

var t = new Thread(InitAndDo); //InitAndDo would have your code creating the webbrowser object etc... t.SetApartmentState(ApartmentState.STA); t.Start();

Luego, el Gotcha, después de finalizar la llamada de navegación, agregue esta línea de código para que pueda obtener el evento de navegación completo:

web.Navigate(Url); Application.Run();