录屏软件的开发


应用程序下载地址: 下载

零、开发准备

这里采用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 200
300 20
在这里插入图片描述
如果不清楚指令格式,可以输入 ScreenRecord.exe –help,将弹出如下窗体,提示命令信息。
在这里插入图片描述

十三、工程文件下载地址

由于OpenCV所占用的文件尺寸比较大,在工程文件中删除了,需要用户自行下载。按照第四章的内容进行添加可以。
工程文件下载地址:下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值