我正在使用
中显示的技术尝试获取网页的屏幕截图我已经能够在WebBrowser
上放置WinForm
控件时获得以下代码才能成功运行。但是,当在线程内运行时,它会通过提供桌面的任意图像而失败。
Thread browserThread = new Thread(() =>
{
WebBrowser br = new WebBrowser();
br.DocumentCompleted += webBrowser1_DocumentCompleted;
br.ProgressChanged += webBrowser1_ProgressChanged;
br.ScriptErrorsSuppressed = true;
br.Navigate(url);
Application.Run();
});
browserThread.SetApartmentState(ApartmentState.STA);
browserThread.Start();
private Image TakeSnapShot(WebBrowser browser)
{
int width;
int height;
width = browser.ClientRectangle.Width;
height = browser.ClientRectangle.Height;
Bitmap image = new Bitmap(width, height);
using (Graphics graphics = Graphics.FromImage(image))
{
Point p = new Point(0, 0);
Point upperLeftSource = browser.PointToScreen(p);
Point upperLeftDestination = new Point(0, 0);
Size blockRegionSize = browser.ClientRectangle.Size;
blockRegionSize.Width = blockRegionSize.Width - 15;
blockRegionSize.Height = blockRegionSize.Height - 15;
graphics.CopyFromScreen(upperLeftSource, upperLeftDestination, blockRegionSize);
}
return image;
}
这很明显是因为方法Graphics.CopyFromScreen()
,但我不知道任何其他方法。有没有办法解决这个问题,任何人都可以建议?或者是我唯一的选择来创建一个表单,添加控件,使其可见,然后屏幕刮?出于显而易见的原因,我希望避免采用这种方法。
答案 0 :(得分:8)
你可以写
private Image TakeSnapShot(WebBrowser browser)
{
browser.Width = browser.Document.Body.ScrollRectangle.Width;
browser.Height= browser.Document.Body.ScrollRectangle.Height;
Bitmap bitmap = new Bitmap(browser.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth, browser.Height);
browser.DrawToBitmap(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height));
return bitmap;
}
完整的工作代码
var image = await WebUtils.GetPageAsImageAsync("http://www.stackoverflow.com");
image.Save(fname , System.Drawing.Imaging.ImageFormat.Bmp);
public class WebUtils
{
public static Task<Image> GetPageAsImageAsync(string url)
{
var tcs = new TaskCompletionSource<Image>();
var thread = new Thread(() =>
{
WebBrowser browser = new WebBrowser();
browser.Size = new Size(1280, 768);
WebBrowserDocumentCompletedEventHandler documentCompleted = null;
documentCompleted = async (o, s) =>
{
browser.DocumentCompleted -= documentCompleted;
await Task.Delay(2000); //Run JS a few seconds more
Bitmap bitmap = TakeSnapshot(browser);
tcs.TrySetResult(bitmap);
browser.Dispose();
Application.ExitThread();
};
browser.ScriptErrorsSuppressed = true;
browser.DocumentCompleted += documentCompleted;
browser.Navigate(url);
Application.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
return tcs.Task;
}
private static Bitmap TakeSnapshot(WebBrowser browser)
{
browser.Width = browser.Document.Body.ScrollRectangle.Width;
browser.Height= browser.Document.Body.ScrollRectangle.Height;
Bitmap bitmap = new Bitmap(browser.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth, browser.Height);
browser.DrawToBitmap(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height));
return bitmap;
}
}
答案 1 :(得分:-1)
using (Graphics graphics = Graphics.FromImage(image))
{
Point p = new Point(0, 0);
Point upperLeftSource = browser.PointToScreen(p);
Point upperLeftDestination = new Point(0, 0);
Size blockRegionSize = browser.ClientRectangle.Size;
blockRegionSize.Width = blockRegionSize.Width - 15;
blockRegionSize.Height = blockRegionSize.Height - 15;
graphics.CopyFromScreen(upperLeftSource, upperLeftDestination, blockRegionSize);
}
你真的需要using statement吗?
您还return image
但是如何分配复制的图像?