Mse*_*ing 2 c# browser screenshot bitmap windows-7
在 c# 中使用 control.drawtobitmap 失败后,我的第二个选择是截取桌面的屏幕截图并裁剪出所需的部分。一旦我切换用户帐户,我的打嗝就会出现,虽然程序不会崩溃,但一旦用户切换,程序只会生成纯黑色图像。
我使用此代码作为参考: WebBrowser.DrawToBitmap() 或其他方法?
我想这在逻辑上是有道理的,因为这将有助于 Windows 节省资源。
在我的情况下,我有哪些选择/解决方案?
编辑 1 对测试代码进行了修改:
int c = 0;
while (true)
{
try
{
c++;
Rectangle formBounds = this.Bounds;
Bitmap bmp = new Bitmap(formBounds.Width, formBounds.Height);
using (Graphics g = Graphics.FromImage(bmp))
g.CopyFromScreen(formBounds.Location, Point.Empty, formBounds.Size);
bmp.Save("picture" + c.ToString() + ".jpg");
Thread.Sleep(5000);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
这在用户帐户上运行良好,但是一旦我切换用户,它就会返回异常:句柄无效。
有任何想法吗?
编辑2:
DrawToBitmap 中的错误不是完全随机的...如果我使用您提供的代码:
Bitmap bmp = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);
this.DrawToBitmap(bmp, this.ClientRectangle);
bmp.Save(".\\picture.jpg");
Run Code Online (Sandbox Code Playgroud)
它完美地工作,例如:http : //oi61.tinypic.com/1z23ynp.jpg
但是,当我右键单击 Web 浏览器控件时,DrawToBitmap 将返回一个空白图像。
示例:http : //oi60.tinypic.com/9ay0yc.jpg
所以我可以通过添加轻松克服这个错误
((Control)webbrowser1).Enabled = false;
Run Code Online (Sandbox Code Playgroud)
这使得在网络浏览器上无法进行任何点击,但不幸的是,停用它会使我的项目变得无用,因为它的主要功能是在网络浏览器控件上模拟鼠标点击。尽管如果窗口被隐藏,这也可能是一个问题。
目前我正在看这篇文章,其中提供了代码来为您提供窗口句柄。
模拟点击进入一个隐藏的窗口, 它似乎有一定的价值...看看吧。
您在使用 DrawToBitmap 时遇到了什么问题?它在这里工作正常,(W8.1,VS2013)即使使用 Webcontrol 并且在切换用户之后也是如此。(但请参阅最后的编辑条件!)
Bitmap bmp = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);
this.DrawToBitmap(bmp, this.ClientRectangle);
// Clipboard.SetImage(bmp); for testing only
bmp.Dispose();
Run Code Online (Sandbox Code Playgroud)
这是截取窗口屏幕截图的代码:
Rectangle formBounds = this.Bounds;
Bitmap bmp = new Bitmap(formBounds.Width, formBounds.Height );
using (Graphics g = Graphics.FromImage(bmp))
g.CopyFromScreen(formBounds.Location, Point.Empty, formBounds.Size);
//Clipboard.SetImage(bmp); for testing only
bmp.Dispose();
Run Code Online (Sandbox Code Playgroud)
我可以随意切换用户,程序继续运行。
BTW,你贴的链接真的很旧,很多东西可能已经改进了。
编辑:
有了更新的问题,事情就清楚多了。
因此,即使用户已更改,您也希望连续获取程序的屏幕截图,对吗?你想显示一个WebControl,对吗?
用户可以拥有三种类型的桌面:登录/注销屏幕、屏幕保护程序屏幕和一个或多个普通桌面屏幕。但是当用户注销时,他根本没有桌面屏幕。
因此,如果用户没有活动桌面,屏幕截图方法将不起作用,既g.CopyFromScreen不会导致 GDI 错误,也不会使用网络上各种解决方案中的窗口句柄,包括您的链接指向的那些。所有这些充其量只会显示一个空白或黑屏。
所以 DrawToBitmap 方法是唯一有效的方法。
你写道它有随机错误。这不是我看到的。
这些问题进来可以预见,当用户交互与WebBrowser以任何方式。这包括在导航或不导航的情况下滚动或单击。在这些交互之后,WebBrowser它将把自己画成一个空框,直到它的 URL 被重新加载 - 不仅刷新 - 而且真的被webBrowser1.Uri = new Uri(uriPath). 这可以做到,请参阅我的另一篇文章
在WebBrowser做的时候也有另外一个问题DrawToBitmap:它会失败(与上述空箱),为包括任何网页<input type="text"元素。我不确定解决这个问题的最佳方法是什么,更不用说为什么它首先发生了..屏幕截图方法没有那个特定的问题。
编辑2:
OP 挖出的代码,使用调用PrintWindow,似乎解决了我们遇到的所有问题:它在注销时工作,即使在单击后也可以使用 Refeshing 并抓取WebBrowser所有页面,包括具有文本输入字段的页面。万岁!
在减少松弛之后,这里是一个版本,可以创建Form或只是WebBroser(或任何其他Control)的副本,带或不带边框:
[DllImport("user32.dll")]
public static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags);
public Bitmap CaptureWindow(Control ctl)
{
//Bitmap bmp = new Bitmap(ctl.Width, ctl.Height); // includes borders
Bitmap bmp = new Bitmap(ctl.ClientRectangle.Width, ctl.ClientRectangle.Height); // content only
using (Graphics graphics = Graphics.FromImage(bmp))
{
IntPtr hDC = graphics.GetHdc();
try { PrintWindow(ctl.Handle, hDC, (uint)0); }
finally { graphics.ReleaseHdc(hDC); }
}
return bmp;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7097 次 |
| 最近记录: |