2011-02-15 13 views
14

¿Es posible dibujar un WebBrowser.Document en un mapa de bits? Básicamente tomando una captura de pantalla de un control WebBrowser (nota, esto es con un WebBrowser que no vive en un formulario, sino solo en el código).Conversión de WebBrowser.Document a un mapa de bits?

WebBrowser w = new WebBrowser(); 
w.Document = "<b>Hello</b> world."; 
w.Document.DrawToBitmap ??? 

¡Gracias!

+2

Creo que la respuesta de @ webspy debe ser aceptado como una mejor respuesta. Las razones para esto son que funciona cuando el navegador no está visible en la pantalla (incluso podría estar fuera de los límites de la pantalla). – ceco

+0

A relacionado q/a: [¿Cómo solucionar un error de opacidad con DrawToBitmap en WebBrowser Control?] (Http://stackoverflow.com/q/21697048/1768303) – Noseratio

Respuesta

1

http://www.bryancook.net/2006/03/screen-capture-for-invisible-windows.html

y aquí:

http://www.codeproject.com/KB/graphics/screen_capturing.aspx

que cree que debería recibir el mango de su control WebBrowser y guardar su contenido como imagen, como se sugiere en esos enlaces.

+0

¿Puede explicar lo que quiere decir con "obtener el control de su Control WebBrowser "? ¡Gracias! :) – sooprise

+0

w.Hwnd o w.Handle no recuerdo ahora ... –

+0

w.Handle Acabo de comprobar – sooprise

24

uso el siguiente código para capturar una captura de pantalla de una página web cargada en un control WebBrowser:

class NativeMethods 
{ 
    [ComImport] 
    [Guid("0000010D-0000-0000-C000-000000000046")] 
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    interface IViewObject 
    { 
     void Draw([MarshalAs(UnmanagedType.U4)] uint dwAspect, int lindex, IntPtr pvAspect, [In] IntPtr ptd, IntPtr hdcTargetDev, IntPtr hdcDraw, [MarshalAs(UnmanagedType.Struct)] ref RECT lprcBounds, [In] IntPtr lprcWBounds, IntPtr pfnContinue, [MarshalAs(UnmanagedType.U4)] uint dwContinue); 
    } 

    [StructLayout(LayoutKind.Sequential, Pack = 4)] 
    struct RECT 
    { 
     public int Left; 
     public int Top; 
     public int Right; 
     public int Bottom; 
    } 

    public static void GetImage(object obj, Image destination, Color backgroundColor) 
    { 
     using(Graphics graphics = Graphics.FromImage(destination)) 
     { 
      IntPtr deviceContextHandle = IntPtr.Zero; 
      RECT rectangle = new RECT(); 

      rectangle.Right = destination.Width; 
      rectangle.Bottom = destination.Height; 

      graphics.Clear(backgroundColor); 

      try 
      { 
       deviceContextHandle = graphics.GetHdc(); 

       IViewObject viewObject = obj as IViewObject; 
       viewObject.Draw(1, -1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, deviceContextHandle, ref rectangle, IntPtr.Zero, IntPtr.Zero, 0); 
      } 
      finally 
      { 
       if(deviceContextHandle != IntPtr.Zero) 
       { 
        graphics.ReleaseHdc(deviceContextHandle); 
       } 
      } 
     } 
    } 
} 

Ejemplo:

Bitmap screenshot = new Bitmap(1024, 768); 
NativeMethods.GetImage(webBrowser.ActiveXInstance, screenshot, Color.White); 
+0

Gracias por este, funciona muy bien. Pero tengo un problema un poco extraño, cuando tomo el render, parece que la imagen está estirada y ampliada (el cuadro de imagen no hace esto). ¿Tienes alguna idea de lo que podría estar causando esto? – Anonymous

+2

La respuesta es bastante simple: cambie el tamaño del navegador web con los métodos Ancho/Alto de la clase WebBrowser. Gracias webspy por este pedazo de código ingenioso. – Anonymous

+0

¡Muchas gracias por esta implementación, webspy! – ceco

2
public void HTMLScreenShot() 
    { 
     WebBrowser wb = new WebBrowser(); 
     wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted); 
     wb.Size = new Size(800, 600); 

     // Add html as string 
     wb.Navigate("about:blank"); 
     wb.Document.Write("<b>Hellow World!</b>"); 
     // Add html from website 
     // wb.Navigate("http://myurl.com"); 

    } 

    void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
    { 
     WebBrowser wb = sender as WebBrowser; 

     using (Bitmap bitmap = new Bitmap(wb.Width, wb.Height)) 
     { 
      Rectangle bounds = new Rectangle(new Point(0, 0), wb.Size); 
      wb.DrawToBitmap(bitmap, bounds); 
      bitmap.Save("C:\WebsiteScreenshot.png"); 
     } 
    } 
1
// 
// If you want to take a snap from existing webBrowser Control 
// 

    private void button1_Click(object sender, EventArgs e) 
    { 
     using (FileDialog fd = new SaveFileDialog()) 
     { 
      fd.Filter = "Image (*.png)|*.png"; 
      if (fd.ShowDialog() == System.Windows.Forms.DialogResult.OK) 
      { 
       new WebPageSnap(webBrowser1.Url.ToString(), fd.FileName); 
       //might take 3 or 4 seconds to save cauz it has to load again. 
      } 
     } 
    } 


// 
// Or if you want to take a snap without showing up 
// 


    private void button2_Click(object sender, EventArgs e) 
    { 
     using (FileDialog fd = new SaveFileDialog()) 
     { 
      fd.Filter = "Image (*.png)|*.png"; 
      if (fd.ShowDialog() == System.Windows.Forms.DialogResult.OK) 
      { 
       string url = "http://www.google.com"; 
       // or 
       url = textBox1.Text; 
       new WebPageSnap(url, fd.FileName);    } 
     } 
    } 

    class WebPageSnap 
    { 
     WebBrowser wb; 
     string outFile; 

     public WebPageSnap(string url, string outputFile) 
     { 
      wb = new WebBrowser(); 
      wb.ProgressChanged += wb_ProgressChanged; 
      outFile = outputFile; 
      wb.ScriptErrorsSuppressed = true; 
      wb.ScrollBarsEnabled = false; 
      wb.Navigate(url); 
     } 

     void wb_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e) 
     { 
      if (e.CurrentProgress == e.MaximumProgress) 
      { 
       wb.ProgressChanged -= wb_ProgressChanged; 
       try 
       { 
        int scrollWidth = 0; 
        int scrollHeight = 0; 

        scrollHeight = wb.Document.Body.ScrollRectangle.Height; 
        scrollWidth = wb.Document.Body.ScrollRectangle.Width; 
        wb.Size = new Size(scrollWidth, scrollHeight); 


        Bitmap bitmap = new Bitmap(wb.Width, wb.Height); 
        for (int Xcount = 0; Xcount < bitmap.Width; Xcount++) 
         for (int Ycount = 0; Ycount < bitmap.Height; Ycount++) 
          bitmap.SetPixel(Xcount, Ycount, Color.Black); 
        wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height)); 
        bitmap.Save(outFile, ImageFormat.Png); 
       } 
       catch { } 
      } 
     } 

    } 
Cuestiones relacionadas