截图方法生成黑色图像
在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()); } }
这在用户帐户上完美运行,但是一旦我切换用户,它就会返回exception:句柄无效。
有任何想法吗?
编辑2:
DrawToBitmap中的错误并不是随机的…如果我使用了您提供的代码:
Bitmap bmp = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height); this.DrawToBitmap(bmp, this.ClientRectangle); bmp.Save(".\picture.jpg");
它完美地运作,例如: http : //oi61.tinypic.com/1z23ynp.jpg
但是,当我右键单击Web浏览器控件时,DrawToBitmap将返回一个空白图像。
例如: http : //oi60.tinypic.com/9ay0yc.jpg
所以我可以通过添加来轻松克服这个错误
((Control)webbrowser1).Enabled = false;
这使得在网络浏览器上无法点击任何内容,但不幸的是,停用它会使我的项目无用,因为它的主要function是模仿Web浏览器控件上的鼠标点击。 虽然如果窗口被隐藏,这也可能是一个问题。
目前我正在看这篇文章,其中提供了代码以提供窗口句柄。
模拟点击进入一个隐藏的窗口似乎它可能有一些价值…看看。
你对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();
以下是获取窗口截图的代码:
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();
我可以像我想的那样切换用户,程序一直在工作。
顺便说一句,你发布的链接真的很旧,很多东西可能都有所改进。
编辑:
随着更新的问题,事情要清楚得多。
因此,即使用户已更改,您也希望不断获取程序的屏幕截图,对吧? 而你想显示一个WebControl,对吧?
用户可以有三种类型的桌面:登录/注销屏幕,屏幕保护程序屏幕和一个或多个普通桌面屏幕。 但是当用户注销时,他根本没有桌面屏幕。
因此,如果用户没有活动桌面,屏幕截图方法将不起作用,既不会像g.CopyFromScreen
那样导致GDI错误,也不会像在网络上的各种解决方案中那样使用窗口句柄,包括链接所导致的那些。 所有这些最多只会显示一个空白或黑屏。
所以DrawToBitmap方法是唯一有效的方法。
你写道它有随机错误。 那不是我看到的。
当用户以任何方式与WebBrowser
交互时,问题就会出现。 这包括滚动或点击带或不带导航。 在这些交互之后, WebBrowser
将自己绘制为一个空框,直到其URL被重新加载 – 不仅刷新 – 而且实际上由webBrowser1.Uri = new Uri(uriPath)
重新加载。 这可以完成,请参阅我的其他post
WebBrowser
在执行DrawToBitmap
时还有另一个问题:对于包含元素的任何页面,它将失败(使用所述空框)。 我不确定解决此问题的最佳方法是什么,更不用说为什么它首先发生了..截图方法没有那个具体问题。
编辑2:
OP挖出代码的代码,通过调用PrintWindow
,似乎解决了我们遇到的所有问题:它在注销时工作,即使在单击WebBrowser
并刮擦所有页面(包括带有文本输入的页面)后也可以使用Refeshing领域。 Hoorah!
在减少松弛之后,这里有一个版本可以创建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; }
最后,即使我切换了用户,这段代码似乎也能正常工作。
用于截取任何未保存的记事本进程的屏幕截图的代码(“Untitled – Notepad”)
private void Form1_Load(object sender, EventArgs e) { //loop for debugging int c = 0; while(true) { c++; System.Drawing.Bitmap image = CaptureWindow(FindWindow(null, "Untitled - Notepad")); image.Save(".\picture"+c.ToString()+".jpg"); Thread.Sleep(5000); } } [DllImport("user32.dll")] public static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags); [DllImport("user32.dll")] public static extern IntPtr GetWindowDC(IntPtr hWnd); [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName); public System.Drawing.Bitmap CaptureWindow(IntPtr hWnd) { System.Drawing.Rectangle rctForm = System.Drawing.Rectangle.Empty; using (System.Drawing.Graphics grfx = System.Drawing.Graphics.FromHdc(GetWindowDC(hWnd))) { rctForm = System.Drawing.Rectangle.Round(grfx.VisibleClipBounds); } System.Drawing.Bitmap pImage = new System.Drawing.Bitmap(rctForm.Width, rctForm.Height); System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(pImage); IntPtr hDC = graphics.GetHdc(); try { PrintWindow(hWnd, hDC, (uint)0); } finally { graphics.ReleaseHdc(hDC); } return pImage; }
请注意,窗口可能是隐藏的,但仍必须在用户帐户上最大化才能获得完整的屏幕截图。
数字版权管理可能会阻止这一点,因为Windows增加了对数字媒体的保护。
例如,如果您尝试使用Microsoft的图形渲染在Media Player或Media Center中创建某些内容的屏幕截图 – 是的,Microsoft将“保护您免受任何潜在的诉讼”。
试试这个:点击键盘上的“Print Screen”,然后进入Microsoft Paint并尝试将屏幕截图粘贴到其中。 有什么吗?
上述就是C#学习教程:截图方法生成黑色图像分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1026843.html