Une façon rapide et sale serait d'utiliser les WinForms WebBrowser de contrôle et de dessiner une image bitmap. Faire cela dans un standalone application console est un peu difficile parce que vous devez être conscient des conséquences de l'hébergement d'un STAThread de contrôle lors de l'utilisation d'un fondamentalement la programmation asynchrone modèle. Mais ici, c'est un travail de preuve de concept qui capture d'une page web à une résolution de 800x600 fichier BMP:
namespace WebBrowserScreenshotSample
{
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using System.Windows.Forms;
class Program
{
[STAThread]
static void Main()
{
int width = 800;
int height = 600;
using (WebBrowser browser = new WebBrowser())
{
browser.Width = width;
browser.Height = height;
browser.ScrollBarsEnabled = true;
// This will be called when the page finishes loading
browser.DocumentCompleted += Program.OnDocumentCompleted;
browser.Navigate("http://stackoverflow.com/");
// This prevents the application from exiting until
// Application.Exit is called
Application.Run();
}
}
static void OnDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
// Now that the page is loaded, save it to a bitmap
WebBrowser browser = (WebBrowser)sender;
using (Graphics graphics = browser.CreateGraphics())
using (Bitmap bitmap = new Bitmap(browser.Width, browser.Height, graphics))
{
Rectangle bounds = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
browser.DrawToBitmap(bitmap, bounds);
bitmap.Save("screenshot.bmp", ImageFormat.Bmp);
}
// Instruct the application to exit
Application.Exit();
}
}
}
Pour compiler cela, créez une nouvelle application console et assurez-vous d'ajouter des références d'assembly pour System.Drawing
et System.Windows.Forms
.
Mise à JOUR: j'ai réécrit le code pour éviter d'avoir à utiliser le hacky interrogation WaitOne/DoEvents modèle. Ce code doit être au plus près en suivant les meilleures pratiques.
Mise à JOUR 2: vous indiquez que Vous voulez l'utiliser dans une application Windows Forms. Dans ce cas, oubliez la création dynamique de l' WebBrowser
contrôle. Ce que vous voulez est de créer un caché (Visible=false) exemple d'un WebBrowser
sur votre formulaire et utiliser de la même façon que je montre ci-dessus. Voici un autre exemple qui montre à l'utilisateur partie du code d'un formulaire avec une zone de texte (webAddressTextBox
), un bouton (generateScreenshotButton
), et une cachée du navigateur (webBrowser
). Alors que je travaillais sur ce, j'ai découvert une particularité que je n'ai pas manipuler avant d' -- le DocumentCompleted événement peut effectivement être soulevée à plusieurs reprises en fonction de la nature de la page. Cet exemple devrait en général, et vous pouvez l'étendre pour faire ce que vous voulez:
namespace WebBrowserScreenshotFormsSample
{
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
public partial class MainForm : Form
{
public MainForm()
{
this.InitializeComponent();
// Register for this event; we'll save the screenshot when it fires
this.webBrowser.DocumentCompleted +=
new WebBrowserDocumentCompletedEventHandler(this.OnDocumentCompleted);
}
private void OnClickGenerateScreenshot(object sender, EventArgs e)
{
// Disable button to prevent multiple concurrent operations
this.generateScreenshotButton.Enabled = false;
string webAddressString = this.webAddressTextBox.Text;
Uri webAddress;
if (Uri.TryCreate(webAddressString, UriKind.Absolute, out webAddress))
{
this.webBrowser.Navigate(webAddress);
}
else
{
MessageBox.Show(
"Please enter a valid URI.",
"WebBrowser Screenshot Forms Sample",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
// Re-enable button on error before returning
this.generateScreenshotButton.Enabled = true;
}
}
private void OnDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
// This event can be raised multiple times depending on how much of the
// document has loaded, if there are multiple frames, etc.
// We only want the final page result, so we do the following check:
if (this.webBrowser.ReadyState == WebBrowserReadyState.Complete &&
e.Url == this.webBrowser.Url)
{
// Generate the file name here
string screenshotFileName = Path.GetFullPath(
"screenshot_" + DateTime.Now.Ticks + ".png");
this.SaveScreenshot(screenshotFileName);
MessageBox.Show(
"Screenshot saved to '" + screenshotFileName + "'.",
"WebBrowser Screenshot Forms Sample",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
// Re-enable button before returning
this.generateScreenshotButton.Enabled = true;
}
}
private void SaveScreenshot(string fileName)
{
int width = this.webBrowser.Width;
int height = this.webBrowser.Height;
using (Graphics graphics = this.webBrowser.CreateGraphics())
using (Bitmap bitmap = new Bitmap(width, height, graphics))
{
Rectangle bounds = new Rectangle(0, 0, width, height);
this.webBrowser.DrawToBitmap(bitmap, bounds);
bitmap.Save(fileName, ImageFormat.Png);
}
}
}
}