录屏软件的开发下载地址https://download.csdn.net/download/chongxing01/12839224
应用程序下载地址: 下载。
零、开发准备
这里采用VS2017+C#+OpenCV的方式实现录屏软件。
准备软件中需要用到的图标文件(“.ico”格式)。可以到“https://www.easyicon.net/”下载。
一、开发任务
可以实现对桌面任意位置,任意尺寸的屏幕进行录屏,并保存为avi文件。并且软件本身可供其他软件调用。
调用命令为:程序名 保存的视频文件名.avi 视频宽度*视频高度 帧率。
目的软件示意图:
二、开发概述
暂无,待补充。
三、创建项目
3.1 新建项目
文件->新建->项目,按照如下配置,新建项目,点击确定进入下一步。
3.2 编辑项目
项目主界面另存,修改主界面类名称为ScreenRecordForm。
文件Form1.cs另存为。如下图所示,点击保存即可。
四、添加OpenCV库
项目->右键->管理NuGet程序包。
搜索OpenCvSharp,选择OpenCVSharp3-AnyCPU安装。如下图所示,点击右边的安装即可,进行安装。
五、添加参数信息
5.1 参数信息
/// <summary>
/// 待保存的文件名
/// </summary>
string save_file_name;
/// <summary>
/// 录屏左上角位置
/// </summary>
Point save_avi_location;
/// <summary>
/// 录屏尺寸
/// </summary>
Size save_avi_size;
/// <summary>
/// 视频帧率
/// </summary>
int save_avi_fps;
/// <summary>
/// 当前保存帧数量
/// </summary>
int frames = 0;
/// <summary>
/// 录屏状态,0:pause, 1:rec, 2:stop
/// </summary>
int status = 0;
/// <summary>
/// 写视频文件对象
/// </summary>
OpenCvSharp.VideoWriter videoWriter;
5.2 应用程序输入参数
5.3.3 修改主窗口的构造函数
public ScreenRecordForm(string[] Args)
{
InitializeComponent();
}
5.3.4 修改应用程序入口函数
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] Args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new ScreenRecordForm(Args));
}
5.3 初始化参数信息
public ScreenCameraForm(string []Args)
{
InitializeComponent();
save_file_name = "C:\\test_video.avi";
save_avi_size = new Size(500, 400);
save_avi_fps = 25;
save_avi_location = new Point(0, 0);
if (Args.Length == 0)
{
}
if(Args.Length >= 1)
{
if(Args[0] == "-help")
{
MessageBox.Show("命令格式:*.exe file_name.avi Width*Height Fps");
Close();
}
save_file_name = Args[0];
}
if (Args.Length >= 2)
{
string []str = Args[1].Split('*');
if (str.Length == 2)
{
try
{
save_avi_size = new Size(Convert.ToInt32(str[0]), Convert.ToInt32(str[1]));
}
catch(Exception ex)
{
Trace.WriteLine(ex.ToString());
}
}
}
if (Args.Length >= 3)
{
try
{
save_avi_fps = Convert.ToInt32(Args[2]);
}
catch(Exception ex)
{
Trace.WriteLine(ex.ToString());
}
if(save_avi_fps<=0)
{
save_avi_fps = 25;
}
}
}
六、添加控件
6.1 添加控件
添加一个Panel容器,用来放置按钮和反馈信息框。
添加三个按钮,“录制、暂停、停止”。
添加一个TextBox编辑框,用来显示反馈信息。
6.2 修改窗体属性
this.Visible = false;
this.FormBorderStyle = FormBorderStyle.None;
this.TopMost = true;
//透明窗体
this.TransparencyKey = Color.Blue;
this.BackColor = Color.Blue;
btnPause.Enabled = false;
panel1.BackColor = Color.WhiteSmoke;
this.Visible = true;
6.3 添加录屏边框
添加窗口尺寸修改和重绘消息响应程序:
由于边框的尺寸线的宽度为4,而录屏的时候不能录制边框,因此,实际的窗口尺寸比录屏所设置的尺寸要大8个像素。
private void ScreenCameraForm_Resize(object sender, EventArgs e)
{
Invalidate();
}
private void ScreenCameraForm_Paint(object sender, PaintEventArgs e)
{
if (BackgroundImage == null)
{
BackgroundImage = new Bitmap(Width, Height);
}
using (Graphics g = Graphics.FromImage(this.BackgroundImage))
{
g.DrawRectangle(
new Pen(Color.Red, 4),
new Rectangle(
save_avi_location.X+2,
save_avi_location.Y+2,
save_avi_size.Width+6,
save_avi_size.Height+6
));
g.Dispose();
}
}
经过如上设置后,运行应用程序,显示如下所示:
七、添加窗口移动消息响应
窗口移动消息响应,包括光标进入改变光标类型,光标离开恢复光标类型,鼠标左键按下,移动鼠标可以拖动窗口,并且鼠标抬起释放窗体移动功能,在窗体上双击可以强制设置坐标为(0,0)。
7.1 添加消息响应函数
为了让整个窗体都有窗口消息响应功能,需要给主窗体和容器都添加消息响应。
this.MouseDoubleClick += new MouseEventHandler(ScreenRecordForm_MouseDoubleClick);
this.MouseDown += new MouseEventHandler(ScreenRecord_MouseDown);
this.MouseMove += new MouseEventHandler(ScreenRecord_MouseMove);
this.MouseUp += new MouseEventHandler(ScreenRecord_MouseUp);
this.MouseEnter += new EventHandler(ScreenRecordForm_MouseEnter);
this.MouseLeave += new EventHandler(ScreenRecordForm_MouseLeave);
panel1.MouseDoubleClick += new MouseEventHandler(ScreenRecordForm_MouseDoubleClick);
panel1.MouseDown += new MouseEventHandler(ScreenRecord_MouseDown);
panel1.MouseMove += new MouseEventHandler(ScreenRecord_MouseMove);
panel1.MouseUp += new MouseEventHandler(ScreenRecord_MouseUp);
panel1.MouseEnter += new EventHandler(ScreenRecordForm_MouseEnter);
panel1.MouseLeave += new EventHandler(ScreenRecordForm_MouseLeave);
7.2 实现双击消息响应函数
private void ScreenRecordForm_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
save_avi_location = new Point(0, 0);
Left = save_avi_location.X - 2;
Top = save_avi_location.Y -2;
}
}
7.3 实现光标进入和离开消息响应函数
private void ScreenRecordForm_MouseEnter(object sender, EventArgs e)
{
this.Cursor = Cursors.SizeAll;
}
private void ScreenRecordForm_MouseLeave(object sender, EventArgs e)
{
this.Cursor = Cursors.Default;
}
7.4 实现鼠标拖动效果
/// <summary>
/// 鼠标按下状态
/// </summary>
bool drag;
/// <summary>
/// 鼠标按下时候的位置坐标
/// </summary>
Point old;
private void ScreenRecord_MouseDown(object sender, MouseEventArgs e)
{
drag = true;
old = e.Location;
}
private void ScreenRecord_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && drag == true)
{
if (sender is Form)
{
Form f = sender as Form;
f.Top = MousePosition.Y - old.Y;
f.Left = MousePosition.X - old.X;
}
else if (sender is Panel)
{
Panel p = sender as Panel;
p.Parent.Top = MousePosition.Y - old.Y - p.Top;
p.Parent.Left = MousePosition.X - old.X - p.Left;
}
save_avi_location = new Point(Location.X + 2, Location.Y + 2);
}
}
private void ScreenRecord_MouseUp(object sender, MouseEventArgs e)
{
drag = false;
}
八、屏幕截图
执行如下函数,直接返回当前坐标,以及当前宽度的位图,这个位图可以直接保存为图片,也可以加入视频帧中。
private Bitmap CaptureScreen(int x, int y, int width, int height)
{
Bitmap bmp = new Bitmap(width, height);
using (Graphics graphics = Graphics.FromImage(bmp))
{
graphics.CopyFromScreen(x, y, 0, 0, new Size(width, height));
graphics.Dispose();
}
return bmp;
}
九、增加按钮消息响应
9.1 启动录屏按钮
private void btnRec_Click(object sender, EventArgs e)
{
btnRec.Enabled = false;
btnPause.Enabled = true;
btnStop.Enabled = true;
if (videoWriter == null)
{
videoWriter = new OpenCvSharp.VideoWriter(
save_file_name, OpenCvSharp.FourCC.XVID,
save_avi_fps,
new OpenCvSharp.Size(save_avi_size.Width, save_avi_size.Height));
}
status = 1;
}
9.2 暂停录屏按钮
private void btnPause_Click(object sender, EventArgs e)
{
status = 0;
btnRec.Enabled = true;
btnPause.Enabled = false;
btnStop.Enabled = true;
}
9.3 停止录屏
按下停止录屏按钮,可以退出软件。
private void btnStop_Click(object sender, EventArgs e)
{
status = 2;
if (videoWriter != null)
{
videoWriter.Release();
}
btnRec.Enabled = true;
btnPause.Enabled = false;
btnStop.Enabled = false;
if (videoWriter != null)
{
DialogResult = DialogResult.OK;
}
else
{
DialogResult = DialogResult.Cancel;
}
Close();
}
十、定时器响应
添加定时器组件,设置时间间隔为100ms,并启用定时器。
定时器是屏幕录制的节点函数,如果视频要求为25帧,则定时器的时间间隔设置为1000/25=40ms。
private void timer1_Tick(object sender, EventArgs e)
{
string str = "";
str += string.Format("X={0},Y={1}\r\n",
save_avi_location.X, save_avi_location.Y
);
str += string.Format("Width={0},Height={1}\r\n",
save_avi_size.Width, save_avi_size.Height);
str += string.Format("Fps={0} ", save_avi_fps);
if (videoWriter!=null && status == 1)
{
videoWriter.Write(BitmapToMat(CaptureScreen(
save_avi_location.X+4,
save_avi_location.Y+4,
save_avi_size.Width,
save_avi_size.Height
)));
frames++;
str += string.Format("Time={0}", frames);
}
str += "\r\n保存路径:" + save_file_name;
textBox1.Text = str;
}
十一、图像格式转换
由于OpenCV中使用的图像格式为Mat,因此这里需要将Bitmap格式转换为Mat才可以使用。
static public OpenCvSharp.Mat BitmapToMat(Bitmap bmp)
{
MemoryStream s2_ms = null;
OpenCvSharp.Mat source = null;
try
{
using (s2_ms = new MemoryStream())
{
bmp.Save(s2_ms, ImageFormat.Bmp);
source = OpenCvSharp.Mat.FromStream(s2_ms, OpenCvSharp.ImreadModes.AnyColor);
}
}
catch (Exception e)
{
Trace.WriteLine(e.ToString());
}
finally
{
if (s2_ms != null)
{
s2_ms.Close();
s2_ms = null;
}
GC.Collect();
}
return source;
}
十二、运行效果
默认保存路径为:“C:\test_video.avi”,默认帧率为25,默认尺寸为500400。
如果需要修改默认参数,需要在执行程序的时候增加输入参数。可以在命令提示符下按照如下的方式执行程序。
执行如下指令:ScreenRecord.exe C:\test.avi 200300 20
如果不清楚指令格式,可以输入 ScreenRecord.exe –help,将弹出如下窗体,提示命令信息。
十三、工程文件下载地址
由于OpenCV所占用的文件尺寸比较大,在工程文件中删除了,需要用户自行下载。按照第四章的内容进行添加可以。
工程文件下载地址:下载。