C# 在线程中执行Webbrowser控件的屏幕scape
我正在使用中显示的技术 当C# 在线程中执行Webbrowser控件的屏幕scape,c#,multithreading,webbrowser-control,screen-scraping,apartments,C#,Multithreading,Webbrowser Control,Screen Scraping,Apartments,我正在使用中显示的技术 当WebBrowser控件放置在WinForm上时,我尝试获取网页的屏幕截图,成功地获得了以下代码。但是,当在线程中运行时,它会提供桌面的任意图像,从而失败 Thread browserThread = new Thread(() => { WebBrowser br = new WebBrowser(); br.DocumentCompleted += webBrowser1_DocumentCompleted; br.ProgressC
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()方法的缘故,但我不知道还有其他方法。有没有任何人可以建议的解决这个问题的方法?或者,我唯一的选择是创建表单、添加控件、使其可见,然后进行屏幕清理?出于显而易见的原因,我希望避免这种做法
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);
}
你真的需要吗
您也返回图像
,但复制的图像是如何分配给它的 你可以写
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);
公共类WebUtils
{
公共静态任务GetPageAsImageAsync(字符串url)
{
var tcs=new TaskCompletionSource();
变量线程=新线程(()=>
{
WebBrowser browser=新的WebBrowser();
browser.Size=新尺寸(1280768);
WebBrowserDocumentCompletedEventHandler documentCompleted=null;
documentCompleted=异步(o,s)=>
{
browser.DocumentCompleted-=DocumentCompleted;
等待任务。延迟(2000);//再运行JS几秒钟
位图位图=快照(浏览器);
tcs.TrySetResult(位图);
browser.Dispose();
Application.ExitThread();
};
browser.ScriptErrorsSuppressed=true;
browser.DocumentCompleted+=DocumentCompleted;
浏览器.导航(url);
Application.Run();
});
SetApartmentState(ApartmentState.STA);
thread.Start();
返回tcs.Task;
}
私有静态位图快照(WebBrowser浏览器)
{
browser.Width=browser.Document.Body.ScrollRectangle.Width;
browser.Height=browser.Document.Body.ScrollRectangle.Height;
位图位图=新位图(browser.Width-System.Windows.Forms.SystemInformation.VerticalScrollBarWidth,browser.Height);
DrawToBitmap(位图,新矩形(0,0,bitmap.Width,bitmap.Height));
返回位图;
}
}
正是我所需要的。我寻找了类似WebBrowser.DrawToBitmap()的东西,但它没有出现在intellisense中(现在仍然没有),但编译很好。非常感谢。同时感谢您显示System.Windows.Forms.SystemInformation。以前从未见过,显然非常有用。太好了。正是我所需要的。不使用语句编写示例代码。唉。@RobertHarvey感谢VS,它很容易解决:)是的,你需要使用,除非你有很好的理由不处理你应该处理的IDisposable对象。对于图像,它是通过线条Graphics=Graphics.FromImage(图像)指定的。
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;
}
}