2009-03-17 11 views

risposta

3

Suggerisco di utilizzare un approccio di terze parti per questo, non farlo da soli. Se insisti, allora, il modo più pesante è usare System.Diagnostics.Process per avviare un browser, quindi lo GetDesktopImage per ottenere uno screenshot.

Sono sicuro che c'è un modo più semplice, ma che assomiglia a questo:

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

Ci sono diversi 3a componenti di partito che fa questo. Apparentemente non è banale, dal momento che cose come Flash e cose non si catturano così facilmente, per esempio.

Ho usato HTMLSnapshot in passato e ne sono rimasto soddisfatto (non è gratuito, ma piuttosto economico).

Mi raccomando vivamente di non sprecare troppo tempo nell'implementazione di questo, perché è destinato a finire per rifare un sacco di casi finali che queste soluzioni di terze parti già gestiscono.

+0

Mi chiedo se qualcuno abbia consigliato Larry Page e Sergey Brin lo stesso: P –

2

Ho cercato in lungo e in largo di trovare una soluzione a questo problema e il problema con l'utilizzo del WebBrowser e altri suggerimenti è che è necessario un sacco di accesso al box.

Per oggi questo è il miglior strumento di terze parti sono stato in grado di trovare:

http://www.websitesscreenshot.com/

loro SEO è terribile, ma credo che li ho trovati su un forum o anche Stack ... I possedere una licenza e ciò che ottieni è solo una singola DLL a cui puoi fare riferimento. Il passaggio di una licenza al costruttore rimuove la filigrana.

Dopo una breve panoramica con ILSpy, credo che quello che fa è che interpreta l'HTML e scarica un'immagine per il piacere della visione.

Uso

Risparmio Un 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(); 

risparmio Raw HTML String

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

È possibile trovare maggiori sulla loro pagina di utilizzo. Trovato qui:

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

Spero che questo aiuti!

Saluti !!

Problemi correlati