E 'possibile scattare una schermata di un dato URL utilizzando il codice .Net?Come si fa a prendere uno screenshot di un sito web tramite il codice .Net?
Qual è il modo più semplice per farlo?
E 'possibile scattare una schermata di un dato URL utilizzando il codice .Net?Come si fa a prendere uno screenshot di un sito web tramite il codice .Net?
Qual è il modo più semplice per farlo?
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;
}
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.
Mi chiedo se qualcuno abbia consigliato Larry Page e Sergey Brin lo stesso: P –
appena imbattuto su questo: http://pietschsoft.com/post/2008/07/C-Generate-WebPage-Thumbmail-Screenshot-Image.aspx
Forse qualcosa che si potrebbe usare?
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 !!
Con quale motore di rendering?Dopo tutto, diversi motori di rendering produrranno risultati diversi –
webkit sembra essere il più conforme agli standard –
wow. non pensavo fosse così facile :) – Karim