新手头顶:为什么我自制的屏幕录像机崩溃了?(c# 和 windows 形式)
Newb over head: Why is my home made screen recorder crashing?(c# and windows forms)
[已解决] Ofir 的解决方案开箱即用。目前 运行 24 f/s 五分钟。
我正在尝试保存屏幕上的图像。
基本上我的问题是,当我降低 Thread.sleep(以创建合适的帧速率)时,程序崩溃了。 thread.sleep 越接近 0,程序崩溃得越快,但我什至找不到问题,因为我从来没有处理过这种东西(如果是 unity3d,我会全力以赴)。
void ScreenCapture()//this is from a youtube tutorial
{
while (true)
{
Bitmap bm = new Bitmap((int)Math.Round(Screen.PrimaryScreen.Bounds.Width * 1.5), (int)Math.Round(Screen.PrimaryScreen.Bounds.Height * 1.5));
//I don't know why I had to multipyly these by 1.5, but it made the screen fit properly.
Graphics g = Graphics.FromImage(bm);
g.CopyFromScreen(0, 0, 0, 0, bm.Size);
pictureBox.Image = bm;
Thread.Sleep(250);
}
}
private void button2_Click(object sender, EventArgs e)
{
Thread t = new Thread(ScreenCapture);
t.Start();
}
我也遇到了一些甜蜜的错误。
'System.ComponentModel.Win32Exception' 类型的未处理异常发生在 System.Drawing.dll
错误代码:-2147467259
我构建了一个 try-catch(我对此知之甚少),但在几次测试后它也坏了,让我看看我是否能得到那个日志。
System.ComponentModel.Win32Exception(0x80004005): The operation completed successfully as System.Drawing.Graphics.CopyFromScreen(Int32 sourceX, Int32 sourceY, Int32 destinationX,Int32 destinationY, Size blockRegionSize)
at Screen_Recorder.Form1.ScreenCapture() in C:Users\Jupiter\Desktop\visual studio experiments\Screen Recorder\ScreenRecorder\Form1.cs:line 35
如果我然后点击确定它说:
System.ArgumentException: Parameter is not valid.
at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
at System.Drawing.Bitmap..ctor(int32 width, Int32 height)
at Screen_Recorder.Form1.ScreenCapture() C:Users\Jupiter\Desktop\visual studio experiments\Screen Recorder\ScreenRecorder\Form1.cs:line 32
然后它将无限重复该错误。
无论如何,我要睡觉了,明天我会再次开始,但在此之前的任何建议将不胜感激!
你有内存泄漏。
Graphics
和 Bitmap
是一次性物品,用完后应该丢弃。
您只能将 Graphics
放在 using
块中,并且在循环的每次迭代中都应处理最后一个位图。
因此,您的代码应如下所示:
private void ScreenCapture()
{
while (true)
{
var bm = new Bitmap((int)Math.Round(Screen.PrimaryScreen.Bounds.Width * 1.5),
(int)Math.Round(Screen.PrimaryScreen.Bounds.Height * 1.5));
using (Graphics g = Graphics.FromImage(bm)) g.CopyFromScreen(0, 0, 0, 0, bm.Size);
// As per the comment by HansPassant - the following would cause
// a thread race with the UI thread.
//this.pictureBox1.Image?.Dispose();
//this.pictureBox1.Image = bm;
// Instead we use beginInvoke to run this on the UI thread
Action action = () =>
{
this.pictureBox1.Image?.Dispose();
this.pictureBox1.Image = bm;
};
this.BeginInvoke(action);
Thread.Sleep(250);
}
}
这个循环永远不会结束(因为 while (true)
),也许你应该考虑添加一个 CancelationToken
并使用 Task
而不是 Thread
。
最后一件事,您应该在完成图片框后将其处理掉。
[已解决] Ofir 的解决方案开箱即用。目前 运行 24 f/s 五分钟。
我正在尝试保存屏幕上的图像。
基本上我的问题是,当我降低 Thread.sleep(以创建合适的帧速率)时,程序崩溃了。 thread.sleep 越接近 0,程序崩溃得越快,但我什至找不到问题,因为我从来没有处理过这种东西(如果是 unity3d,我会全力以赴)。
void ScreenCapture()//this is from a youtube tutorial
{
while (true)
{
Bitmap bm = new Bitmap((int)Math.Round(Screen.PrimaryScreen.Bounds.Width * 1.5), (int)Math.Round(Screen.PrimaryScreen.Bounds.Height * 1.5));
//I don't know why I had to multipyly these by 1.5, but it made the screen fit properly.
Graphics g = Graphics.FromImage(bm);
g.CopyFromScreen(0, 0, 0, 0, bm.Size);
pictureBox.Image = bm;
Thread.Sleep(250);
}
}
private void button2_Click(object sender, EventArgs e)
{
Thread t = new Thread(ScreenCapture);
t.Start();
}
我也遇到了一些甜蜜的错误。
'System.ComponentModel.Win32Exception' 类型的未处理异常发生在 System.Drawing.dll
错误代码:-2147467259
我构建了一个 try-catch(我对此知之甚少),但在几次测试后它也坏了,让我看看我是否能得到那个日志。
System.ComponentModel.Win32Exception(0x80004005): The operation completed successfully as System.Drawing.Graphics.CopyFromScreen(Int32 sourceX, Int32 sourceY, Int32 destinationX,Int32 destinationY, Size blockRegionSize)
at Screen_Recorder.Form1.ScreenCapture() in C:Users\Jupiter\Desktop\visual studio experiments\Screen Recorder\ScreenRecorder\Form1.cs:line 35
如果我然后点击确定它说:
System.ArgumentException: Parameter is not valid.
at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
at System.Drawing.Bitmap..ctor(int32 width, Int32 height)
at Screen_Recorder.Form1.ScreenCapture() C:Users\Jupiter\Desktop\visual studio experiments\Screen Recorder\ScreenRecorder\Form1.cs:line 32
然后它将无限重复该错误。
无论如何,我要睡觉了,明天我会再次开始,但在此之前的任何建议将不胜感激!
你有内存泄漏。
Graphics
和 Bitmap
是一次性物品,用完后应该丢弃。
您只能将 Graphics
放在 using
块中,并且在循环的每次迭代中都应处理最后一个位图。
因此,您的代码应如下所示:
private void ScreenCapture()
{
while (true)
{
var bm = new Bitmap((int)Math.Round(Screen.PrimaryScreen.Bounds.Width * 1.5),
(int)Math.Round(Screen.PrimaryScreen.Bounds.Height * 1.5));
using (Graphics g = Graphics.FromImage(bm)) g.CopyFromScreen(0, 0, 0, 0, bm.Size);
// As per the comment by HansPassant - the following would cause
// a thread race with the UI thread.
//this.pictureBox1.Image?.Dispose();
//this.pictureBox1.Image = bm;
// Instead we use beginInvoke to run this on the UI thread
Action action = () =>
{
this.pictureBox1.Image?.Dispose();
this.pictureBox1.Image = bm;
};
this.BeginInvoke(action);
Thread.Sleep(250);
}
}
这个循环永远不会结束(因为 while (true)
),也许你应该考虑添加一个 CancelationToken
并使用 Task
而不是 Thread
。
最后一件事,您应该在完成图片框后将其处理掉。