Progtwigr programáticamente una captura de pantalla de una página

Estoy escribiendo un rastreador y analizador especializado para uso interno, y requiero la capacidad de tomar una captura de pantalla de una página web para verificar qué colores se usan en todo momento. El progtwig tomará alrededor de diez direcciones web y las guardará como una imagen de bitmap.

Desde allí planeo usar LockBits para crear una lista de los cinco colores más usados ​​dentro de la imagen. Que yo sepa, es la forma más fácil de obtener los colores utilizados en una página web, pero si hay una manera más fácil de hacerlo, por favor, repita con sus sugerencias.

De todos modos, iba a utilizar ACA WebThumb ActiveX Control hasta que vi la etiqueta de precio. También soy bastante nuevo en C #, solo lo he usado durante unos meses. ¿Hay alguna solución a mi problema de tomar una captura de pantalla de una página web para extraer el esquema de colores?

https://www.url2png.com/docs es bueno. Ellos tienen un nivel gratis.

Tendrá que usar HttpWebRequest para descargar el binario de la imagen. Aquí hay un ejemplo:

HttpWebRequest request = HttpWebRequest.Create("https://api.url2png.com/v6/[API_KEY]/[API_TOKEN]/png/?url=[URL]") as HttpWebRequest; Bitmap bitmap; using (Stream stream = request.GetResponse().GetResponseStream()) { bitmap = new Bitmap(stream); } // now that you have a bitmap, you can do what you need to do... 

Para generar la URL …

 public static string url2png(string UrlToSite) { string url2pngAPIKey = "PXXX"; string url2pngPrivateKey = "SXXX"; string url = HttpUtility.UrlEncode(UrlToSite); string getstring = "fullpage=true&url=" + url; string SecurityHash_url2png = Md5HashPHPCompliant(url2pngPrivateKey + "+" + getstring).ToLower(); var url2pngLink = "http://api.url2png.com/v6/" + url2pngAPIKey + "/" + SecurityHash_url2png + "/" + "png/?" + getstring; return url2pngLink; } public static string Md5HashPHPCompliant(string pass) { System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); byte[] dataMd5 = md5.ComputeHash(Encoding.UTF8.GetBytes(pass)); StringBuilder sb = new StringBuilder(); for (int i = 0; i < = dataMd5.Length - 1; i++) { sb.AppendFormat("{0:x2}", dataMd5[i]); } return sb.ToString(); } 

Una forma rápida y sucia sería utilizar el control WinForms WebBrowser y dibujarlo en un bitmap. Hacer esto en una aplicación de consola independiente es un poco complicado porque debes ser consciente de las implicaciones de alojar un control STAThread mientras usas un patrón de progtwigción fundamentalmente asincrónico. Pero aquí hay una prueba de concepto que captura una página web en un archivo BMP de 800×600:

 namespace WebBrowserScreenshotSample { using System; using System.Drawing; using System.Drawing.Imaging; using System.Threading; using System.Windows.Forms; class Program { [STAThread] static void Main() { int width = 800; int height = 600; using (WebBrowser browser = new WebBrowser()) { browser.Width = width; browser.Height = height; browser.ScrollBarsEnabled = true; // This will be called when the page finishes loading browser.DocumentCompleted += Program.OnDocumentCompleted; browser.Navigate("https://stackoverflow.com/"); // This prevents the application from exiting until // Application.Exit is called Application.Run(); } } static void OnDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { // Now that the page is loaded, save it to a bitmap WebBrowser browser = (WebBrowser)sender; using (Graphics graphics = browser.CreateGraphics()) using (Bitmap bitmap = new Bitmap(browser.Width, browser.Height, graphics)) { Rectangle bounds = new Rectangle(0, 0, bitmap.Width, bitmap.Height); browser.DrawToBitmap(bitmap, bounds); bitmap.Save("screenshot.bmp", ImageFormat.Bmp); } // Instruct the application to exit Application.Exit(); } } } 

Para comstackr esto, cree una nueva aplicación de consola y asegúrese de agregar referencias de ensamblado para System.Drawing y System.Windows.Forms .

ACTUALIZACIÓN: Reescribí el código para evitar tener que usar el patrón de votación pirata WaitOne / DoEvents. Este código debería estar más cerca de seguir las mejores prácticas.

ACTUALIZACIÓN 2: indica que desea utilizar esto en una aplicación de Windows Forms. En ese caso, olvídese de crear dinámicamente el control WebBrowser . Lo que quiere es crear una instancia oculta (Visible = falsa) de un WebBrowser en su formulario y usarla de la misma manera que la mostrada arriba. Aquí hay otra muestra que muestra la parte del código de usuario de un formulario con un cuadro de texto ( webAddressTextBox ), un botón ( generateScreenshotButton ) y un navegador oculto ( webBrowser ). Mientras estaba trabajando en esto, descubrí una peculiaridad que no manejé antes: el evento DocumentCompleted puede en realidad plantearse varias veces dependiendo de la naturaleza de la página. Esta muestra debería funcionar en general, y puede ampliarla para hacer lo que desee:

 namespace WebBrowserScreenshotFormsSample { using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Windows.Forms; public partial class MainForm : Form { public MainForm() { this.InitializeComponent(); // Register for this event; we'll save the screenshot when it fires this.webBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(this.OnDocumentCompleted); } private void OnClickGenerateScreenshot(object sender, EventArgs e) { // Disable button to prevent multiple concurrent operations this.generateScreenshotButton.Enabled = false; string webAddressString = this.webAddressTextBox.Text; Uri webAddress; if (Uri.TryCreate(webAddressString, UriKind.Absolute, out webAddress)) { this.webBrowser.Navigate(webAddress); } else { MessageBox.Show( "Please enter a valid URI.", "WebBrowser Screenshot Forms Sample", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); // Re-enable button on error before returning this.generateScreenshotButton.Enabled = true; } } private void OnDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { // This event can be raised multiple times depending on how much of the // document has loaded, if there are multiple frames, etc. // We only want the final page result, so we do the following check: if (this.webBrowser.ReadyState == WebBrowserReadyState.Complete && e.Url == this.webBrowser.Url) { // Generate the file name here string screenshotFileName = Path.GetFullPath( "screenshot_" + DateTime.Now.Ticks + ".png"); this.SaveScreenshot(screenshotFileName); MessageBox.Show( "Screenshot saved to '" + screenshotFileName + "'.", "WebBrowser Screenshot Forms Sample", MessageBoxButtons.OK, MessageBoxIcon.Information); // Re-enable button before returning this.generateScreenshotButton.Enabled = true; } } private void SaveScreenshot(string fileName) { int width = this.webBrowser.Width; int height = this.webBrowser.Height; using (Graphics graphics = this.webBrowser.CreateGraphics()) using (Bitmap bitmap = new Bitmap(width, height, graphics)) { Rectangle bounds = new Rectangle(0, 0, width, height); this.webBrowser.DrawToBitmap(bitmap, bounds); bitmap.Save(fileName, ImageFormat.Png); } } } } 

Esta pregunta es antigua pero, alternativamente, puedes usar el paquete nuget Freezer . Es gratis, utiliza un navegador web Gecko reciente (es compatible con HTML5 y CSS3) y se encuentra solo en una dll.

 var screenshotJob = ScreenshotJobBuilder.Create("https://google.com") .SetBrowserSize(1366, 768) .SetCaptureZone(CaptureZone.FullPage) .SetTrigger(new WindowLoadTrigger()); System.Drawing.Image screenshot = screenshotJob.Freeze(); 

Existe un gran navegador basado en Webkit PhantomJS que permite ejecutar cualquier JavaScript desde la línea de comandos.

Instálelo desde http://phantomjs.org/download.html y ejecute el siguiente script de muestra desde la línea de comandos:

 ./phantomjs ../examples/rasterize.js http://sofes.miximages.com/c%23/76188108 test.jpg 

Creará una captura de pantalla de una página determinada en un archivo JPEG. La ventaja de ese enfoque es que no confía en ningún proveedor externo y puede automatizar fácilmente la captura de pantalla en grandes cantidades.

Mira esto . Esto parece hacer lo que usted quería y técnicamente aborda el problema de manera muy similar a través del control del navegador web. Parece que se ha adaptado para que se pasen una serie de parámetros y también se incorpore un buen manejo de errores. El único inconveniente es que se trata de un proceso externo (exe) que generas y crea un archivo físico que leerás más adelante. Según su descripción, incluso considera servicios web, por lo que no creo que sea un problema.

Al resolver su último comentario sobre cómo procesar varios de ellos simultáneamente, esto será perfecto. Puede generar un paralelo de 3, 4, 5 o más procesos en cualquier momento o hacer que el análisis del bit de color se ejecute como hilo mientras se está produciendo otro proceso de captura.

Para el procesamiento de imágenes, recientemente me encontré con Emgu , no lo he usado pero parece fascinante. Afirma ser rápido y tiene mucho soporte para el análisis gráfico, incluida la lectura del color del píxel. Si tengo algún proyecto de procesamiento gráfico disponible en este momento, intentaré esto.

también puedes echarle un vistazo a QT jambi http://qt.nokia.com/doc/qtjambi-4.4/html/com/trolltech/qt/qtjambi-index.html

tienen una buena implementación java basada en webkit para un navegador donde puedes hacer una captura de pantalla simplemente haciendo algo como:

  QPixmap pixmap; pixmap = QPixmap.grabWidget(browser); pixmap.save(writeTo, "png"); 

Echa un vistazo a las muestras: tienen una buena demo de webbrowser.

Usé WebBrowser y no funciona perfecto para mí, especialmente cuando hay que esperar a que se complete la renderización de JavaScript. Probé algunos Api (s) y encontré Selenium , lo más importante sobre Selenium es que no requiere STAThread y podría ejecutarse en una aplicación de consola sencilla, así como en Servicios.

darle una oportunidad :

 class Program { static void Main() { var driver = new FirefoxDriver(); driver.Navigate() .GoToUrl("http://sofes.miximages.com/c%23/); driver.GetScreenshot() .SaveAsFile(stackoverflow.jpg", ImageFormat.Jpeg); driver.Quit(); } }