对于初学者来说,我知道已经有关于此的主题,但是我似乎找不到适合我需要的答案,经过大约4个月的研究,我决定在这里提出一个问题.
对于项目,我需要使屏幕截图具有周期性.这些屏幕截图是根据用户参数(是否使用显示器)或截取屏幕截图的区域而创建的. (这意味着屏幕截图可能仅是显示内容的一半左右.)
问题是,它的速度很慢…
是的,我知道,如果我想更快地执行此操作,则必须使用此库或该DirectX等.
但是:我既不知道DirectX,也找不到能够返回位图数据条带的开源库(并且确实更快).
我也尝试了一些使用DirectX制作屏幕截图的教程,但无法使其正常运行.
关于性能问题,当仅使用1个显示器时,性能实际上并没有那么差. (对于1440p分辨率,截图约为40毫秒)
真正糟糕的是DWM. (我猜是dwm).
制作屏幕截图时,除在窗口中拖动外,其他所有操作均正常.就像在youtube上观看视频一样.但是,当我开始在窗户周围四处走动时,它慢得要命.似乎在我截屏时拖动动画被阻止了.
现在是我的一个或多个问题:
>有人知道这种行为和/或有解决方案吗?
>我有哪些选择(严重的选择.我的意思是在30ms的选择中像3x 1440p)
编辑:这是我用来制作屏幕截图的方法
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]);
}
}
解决方法:
我已经使用了一个非常简单且稳定的解决方案来进行屏幕捕获和实时流传输,但是它确实使用了外部库.可能是您可以花几分钟时间看一下. 1600×900的屏幕捕捉时间为6-15毫秒.
所以,你需要-
> Mirage驱动程序,您可以在这里获得:
http://www.demoforge.com/dfmirage.htm
>此示例应用程序:
http://www.demoforge.com/sdk/MirrSharp.zip
我已经修改了示例解决方案的代码,以在每次触发桌面更改事件时在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);
}