Ответ 1
Просто наткнулся на это: http://pietschsoft.com/post/2008/07/C-Generate-WebPage-Thumbmail-Screenshot-Image.aspx
Может быть, вы могли бы использовать?
Можно ли снять снимок экрана с любого URL-адреса, используя код .Net?
Каков самый простой способ сделать это?
Просто наткнулся на это: http://pietschsoft.com/post/2008/07/C-Generate-WebPage-Thumbmail-Screenshot-Image.aspx
Может быть, вы могли бы использовать?
Я бы предложил использовать сторонний подход для этого, не делая этого самостоятельно. Однако, если вы настаиваете, то тяжелый способ - использовать System.Diagnostics.Process
для запуска браузера, затем GetDesktopImage
, чтобы получить снимок экрана.
Я уверен, что есть более простой способ, но это выглядит так:
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;
}
Есть несколько сторонних компонентов, которые делают это. По-видимому, это не тривиально, так как такие вещи, как Flash и прочее, не так легко захватываются, например.
Я использовал HTMLSnapshot в прошлом и был доволен им (он не бесплатный, но довольно дешевый).
Я сердечно предлагаю вам не тратить слишком много времени на реализацию этого, потому что вы обязательно закончите переделывать множество конечных случаев, которые уже разрешены этими сторонними решениями.
Я искал широко и широко, чтобы найти решение этой проблемы, и проблема с использованием WebBrowser и других предложений заключается в том, что вам нужен большой доступ к коробке.
На сегодняшний день это лучший сторонний инструмент, который я смог найти:
http://www.websitesscreenshot.com/
Их SEO ужасен, но я считаю, что нашел их на форуме или даже в Stack... У меня есть лицензия, и вы получаете только одну DLL, которую вы можете ссылаться. Передача лицензии конструктору удаляет водяной знак.
После быстрого просмотра с помощью ILSpy я считаю, что он делает то, что он интерпретирует HTML и сбрасывает изображение для вашего удовольствия.
Использование
Сохранение 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();
Сохранение исходной HTML-строки
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();
Вы можете найти больше на странице использования. Найдено здесь:
http://www.websitesscreenshot.com/Usage.html
Надеюсь, это поможет!
Ура!!