2009-03-17 8 views
13

Est-il possible de prendre une capture d'écran d'une URL donnée en utilisant le code .Net?Comment prendre une capture d'écran d'un site Web via le code .Net?

Quelle est la manière la plus facile de le faire?

+0

Avec quel moteur de rendu?Après tout, différents moteurs de rendu produiront des résultats différents. –

+0

webkit semble être le plus conforme aux normes –

+0

wow. Je ne pense pas que c'était si facile :) – Karim

Répondre

3

Je suggérerais d'utiliser une approche tierce pour cela, ne pas le faire vous-même. Si vous insistez, cependant, le plus dur est d'utiliser System.Diagnostics.Process pour lancer un navigateur, puis GetDesktopImage pour obtenir une capture d'écran.

Je suis sûr qu'il ya un moyen plus facile, mais qui ressemble à ceci:

using System; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.Runtime.InteropServices; 

public class PlatformInvokeGDI32 
{ 
    public const int SRCCOPY = 13369376; 

    [DllImport("gdi32.dll",EntryPoint="DeleteDC")] 
    public static extern IntPtr DeleteDC(IntPtr hDc); 

    [DllImport("gdi32.dll",EntryPoint="DeleteObject")] 
    public static extern IntPtr DeleteObject(IntPtr hDc); 

    [DllImport("gdi32.dll",EntryPoint="BitBlt")] 
    public static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, int RasterOp); 

    [DllImport ("gdi32.dll",EntryPoint="CreateCompatibleBitmap")] 
    public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc,int nWidth, int nHeight); 

    [DllImport ("gdi32.dll",EntryPoint="CreateCompatibleDC")] 
    public static extern IntPtr CreateCompatibleDC(IntPtr hdc); 

    [DllImport ("gdi32.dll",EntryPoint="SelectObject")] 
    public static extern IntPtr SelectObject(IntPtr hdc,IntPtr bmp); 
} 

public class PlatformInvokeUSER32 
{ 
    public const int SM_CXSCREEN = 0; 
    public const int SM_CYSCREEN = 1; 

    [DllImport("user32.dll", EntryPoint="GetDesktopWindow")] 
    public static extern IntPtr GetDesktopWindow(); 

    [DllImport("user32.dll",EntryPoint="GetDC")] 
    public static extern IntPtr GetDC(IntPtr ptr); 

    [DllImport("user32.dll",EntryPoint="GetSystemMetrics")] 
    public static extern int GetSystemMetrics(int abc); 

    [DllImport("user32.dll",EntryPoint="GetWindowDC")] 
    public static extern IntPtr GetWindowDC(Int32 ptr); 

    [DllImport("user32.dll",EntryPoint="ReleaseDC")] 
    public static extern IntPtr ReleaseDC(IntPtr hWnd,IntPtr hDc); 
} 

public class CaptureScreen 
{ 
    public static Bitmap GetDesktopImage() 
    { 
     //In size variable we shall keep the size of the screen. 
     SIZE size; 

     //Variable to keep the handle to bitmap. 
     IntPtr hBitmap; 

     //Here we get the handle to the desktop device context. 
     IntPtr hDC = PlatformInvokeUSER32.GetDC(PlatformInvokeUSER32.GetDesktopWindow()); 

     //Here we make a compatible device context in memory for screen device context. 
     IntPtr hMemDC = PlatformInvokeGDI32.CreateCompatibleDC(hDC); 

     //We pass SM_CXSCREEN constant to GetSystemMetrics to get the 
     //X coordinates of the screen. 
     size.cx = PlatformInvokeUSER32.GetSystemMetrics(PlatformInvokeUSER32.SM_CXSCREEN); 

     //We pass SM_CYSCREEN constant to GetSystemMetrics to get the Y coordinates of the screen. 
     size.cy = PlatformInvokeUSER32.GetSystemMetrics (PlatformInvokeUSER32.SM_CYSCREEN); 

     //We create a compatible bitmap of the screen size and using the screen device context. 
     hBitmap = PlatformInvokeGDI32.CreateCompatibleBitmap(hDC, size.cx, size.cy); 

     //As hBitmap is IntPtr, we cannot check it against null. 
     //For this purpose, IntPtr.Zero is used. 
     if(hBitmap != IntPtr.Zero) 
     { 
      //Here we select the compatible bitmap in the memeory device 
      //context and keep the refrence to the old bitmap. 
      IntPtr hOld = (IntPtr) PlatformInvokeGDI32.SelectObject(hMemDC, hBitmap); 

      //We copy the Bitmap to the memory device context. 
      PlatformInvokeGDI32.BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, PlatformInvokeGDI32.SRCCOPY); 

      //We select the old bitmap back to the memory device context. 
      PlatformInvokeGDI32.SelectObject(hMemDC, hOld); 

      //We delete the memory device context. 
      PlatformInvokeGDI32.DeleteDC(hMemDC); 

      //We release the screen device context. 
      PlatformInvokeUSER32.ReleaseDC(PlatformInvokeUSER32.GetDesktopWindow(), hDC); 

      //Image is created by Image bitmap handle and stored in local variable. 
      Bitmap bmp = System.Drawing.Image.FromHbitmap(hBitmap); 

      //Release the memory to avoid memory leaks. 
      PlatformInvokeGDI32.DeleteObject(hBitmap); 

      //This statement runs the garbage collector manually. 
      GC.Collect(); 

      //Return the bitmap 
      return bmp; 
     } 

     //If hBitmap is null, retun null. 
     return null; 
    } 
} 

//This structure shall be used to keep the size of the screen. 
public struct SIZE 
{ 
    public int cx; 
    public int cy; 
} 
2

Il y a plusieurs composants 3ème partie qui fait cela. Apparemment, ce n'est pas trivial, puisque des choses comme Flash et d'autres choses ne se capturent pas aussi facilement, par exemple. Par le passé, j'ai utilisé HTMLSnapshot et j'étais satisfait (ce n'est pas gratuit, mais pas cher). Je vous suggère de ne pas perdre trop de temps à l'implémenter vous-même, car vous finirez par refaire beaucoup de cas que ces solutions tierces traitent déjà.

+0

Je me demande si quelqu'un a conseillé Larry Page et Sergey Brin la même chose: P –

2

J'ai cherché loin et large pour trouver une solution à ce problème et le problème avec l'utilisation de WebBrowser et d'autres suggestions est que vous avez besoin de beaucoup d'accès à la boîte.

À ce jour, c'est le meilleur outil tiers que j'ai pu trouver:

http://www.websitesscreenshot.com/

Leur SEO est terrible, mais je crois que je les ai trouvés sur un forum ou même pile ... I Possédez une licence et ce que vous obtenez est juste une seule DLL que vous pouvez référencer. Passer une licence au constructeur supprime leur filigrane. Après un rapide coup d'oeil avec ILSpy, je crois que ce qu'il fait, c'est qu'il interprète le code HTML et décharge une image pour votre plus grand plaisir.

Utilisation

Enregistrement URL

WebsitesScreenshot.WebsitesScreenshot _Obj; 
_Obj = new WebsitesScreenshot.WebsitesScreenshot(); 
WebsitesScreenshot.WebsitesScreenshot.Result _Result; 
_Result = _Obj.CaptureWebpage("http://www.google.com"); 
if (_Result == WebsitesScreenshot.WebsitesScreenshot.Result.Captured) 
{ 
    _Obj.ImageFormat = WebsitesScreenshot. 
     WebsitesScreenshot.ImageFormats.PNG; 
    _Obj.SaveImage ("c:\\google.png"); 
}    
_Obj.Dispose(); 

Saving HTML brut Chaîne

WebsitesScreenshot.WebsitesScreenshot _Obj; 
_Obj=new WebsitesScreenshot.WebsitesScreenshot(); 
WebsitesScreenshot.WebsitesScreenshot.Result _Result; 
_Result = _Obj.CaptureHTML(
"<html><body><h1> Hello world </h1></body></html>"); 
if (_Result == WebsitesScreenshot.WebsitesScreenshot.Result.Captured) 
{ 
    _Obj.ImageFormat = WebsitesScreenshot. 
     WebsitesScreenshot.ImageFormats.GIF; 
    _Obj.SaveImage("c:\\test.gif"); 
} 
_Obj.Dispose(); 

Vous pouvez trouver plus sur leur page d'utilisation. Trouvé ici:

http://www.websitesscreenshot.com/Usage.html

Hope this helps!

À la vôtre !!

Questions connexes