对于一个项目,我需要制作截图周期性的。这些屏幕截图是根据用户参数进行的,无论是否使用显示器或截取屏幕截图的区域。 (这意味着屏幕截图只能来自显示屏的一半左右。)
事情是,它的速度很慢...... 是的我知道,如果我想更快地完成它,我必须使用这个库或者directx等等。 但是:我也不知道directx,也没有找到能够返回位图数据条带的开源文件(并且真的更快)。 此外,我已经尝试了一些使用directx制作屏幕截图的教程,但无法使其正常运行。关于性能问题,当仅使用1个显示器时,性能实际上并不那么糟糕。 (对于1440p分辨率,屏幕截图约为40ms)
真正糟糕的是DWM。 (我猜它的dwm)。 在制作屏幕截图时,一切都是正常的,除非在窗户周围徘徊。就像在youtube上观看视频一样好。但是,当我开始在窗户周围移动时,它的速度很慢。当我拍摄截图时,似乎阻止了拖动动画。
现在提出我的问题(或问题):
编辑:这是我用来制作屏幕截图的方法
public void makeScreenshot(int i)
{
if (DisplayList[i].UseDisplay)
{
// copy from screen into graphics
this.graphicsList[i].CopyFromScreen(Screen.AllScreens[DisplayList[i].DisplayNo].Bounds.X, AreaTop[i], 0, 0, sizeList[i], CopyPixelOperation.SourceCopy);
// bitmapData is filled with LockBits from Screenshotted Bmp
bitmapData[i] = this.bitmapList[i].LockBits(rect[i], ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
// Pointer set to first pixel of Bitmap data
Iptr[i] = bitmapData[i].Scan0;
// Now Marshalcopy bitmapData to Pixel Array
Marshal.Copy(Iptr[i], Pixels[i], 0, Pixels[i].Length);
// Finaly unlock bits of Bitmap for next run
this.bitmapList[i].UnlockBits(bitmapData[i]);
}
}
答案 0 :(得分:4)
我已经使用了一个非常简单而稳定的解决方案,用于屏幕捕获和实时流媒体,但它确实使用了外部库。也许你可以花几分钟来看看这个。 1600x900截屏时我得到了6-15ms。 所以,你需要 -
我修改了示例解决方案的代码,以便每次触发桌面更改事件时在PictureBox控件中显示屏幕。像这样:
private void _mirror_DesktopChange(object sender, DesktopMirror.DesktopChangeEventArgs e)
{
Trace.WriteLine(string.Format("Changed rect is {0},{1} ; {2}, {3} ({4})", new object[] { e.x1, e.y1, e.x2, e.y2, e.type }));
var perf = new Stopwatch();
perf.Start();
var bitmap = _mirror.GetScreen();
perf.Stop();
label1.Invoke(new Action<Int64>(i =>
{
pictureBox1.Image = bitmap;
label1.Text = i.ToString();
}), perf.ElapsedMilliseconds);
}
答案 1 :(得分:0)
如果您关心性能,则不应使用GDI来阅读桌面。
DWM: Performance Considerations and Best Practices
避免读取或写入显示器DC。尽管受DWM支持,但由于性能下降,我们不推荐使用它。
虽然你没有这样做,但some DirectDraw applications tried to lock the entire desktop window要画画。在Windows 7 applications that attempt that operation will fail中 - 除了缓慢之外:
DirectDraw Lock
- Windows 7 :针对Windows 7显示的应用程序无法调用DDRAW中的Lock API来锁定主桌面视频缓冲区。这样做会导致错误,并且将返回主要的 NULL 指针。即使未打开桌面窗口管理器组合,也会强制执行此行为。 Windows 7兼容的应用程序不得锁定主视频缓冲区以进行渲染。
- Windows Vista(默认):应用程序将能够获取主视频缓冲区上的锁定,因为旧应用程序依赖于此行为。运行该应用程序将关闭桌面窗口管理器。