通过C#代码实现开启摄像头,截图,录像等功能

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
namespace CustomControl
{
    public partial class WebCamControl : UserControl
    {
        public WebCamControl()
        {
            InitializeComponent();
            mControlPtr = pictureBox1.Handle;
        }
        /// <summary>
        /// 抓图完成
        /// </summary>
        public event Action<string> GrabImageCompleted;
        /// <summary>
        /// 录像完成
        /// </summary>
        public event Action<string> KinescopeCompleted;
        /// <summary>
        /// 开始录像,用以激活当前窗体,如果不激活显示的图像将出现条纹,影响观感
        /// </summary>
        public event EventHandler StartKinescope;
        bool isActive = false;
        [Browsable(true), Category("自定义属性"), Description("是否开启摄像头")]
        public bool IsActive
        {
            get
            {
                return isActive;
            }
            set
            {
                isActive = value;
                if (isActive)
                {
                    mLeft = 0;
                    mTop = 0;
                    mWidth = pictureBox1.Width;
                    mHeight = pictureBox1.Height;
                    Start();
                }
                else
                {
                    Stop();
                }
            }
        }
        /// <summary>
        /// 相机是否开启
        /// </summary>
        [Browsable(true), Category("自定义属性"), Description("摄像头是否已开启")]
        public bool IsOpen
        {
            get
            {
                return bStat;
            }
        }
        const int WM_USER = 0x400;
        const int WS_CHILD = 0x40000000;
        const int WS_VISIBLE = 0x10000000;
        const int WM_CAP_START = WM_USER;
        const int WM_CAP_STOP = WM_CAP_START + 68;
        const int WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;
        const int WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;
        const int WM_CAP_SAVEDIB = WM_CAP_START + 25;
        const int WM_CAP_GRAB_FRAME = WM_CAP_START + 60;
        const int WM_CAP_SEQUENCE = WM_CAP_START + 62;
        const int WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20;
        const int WM_CAP_SEQUENCE_NOFILE = WM_CAP_START + 63;
        const int WM_CAP_SET_OVERLAY = WM_CAP_START + 51;
        const int WM_CAP_SET_PREVIEW = WM_CAP_START + 50;
        const int WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_CAP_START + 6;
        const int WM_CAP_SET_CALLBACK_ERROR = WM_CAP_START + 2;
        const int WM_CAP_SET_CALLBACK_STATUSA = WM_CAP_START + 3;
        const int WM_CAP_SET_CALLBACK_FRAME = WM_CAP_START + 5;
        const int WM_CAP_SET_SCALE = WM_CAP_START + 53;
        const int WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52;
        const int WM_CAP_SET_EDIT_COPY = WM_CAP_START + 30;
        IntPtr hWndc;
        bool bStat;
        IntPtr mControlPtr;
        int mWidth;
        int mHeight;
        int mLeft;
        int mTop;
        string grabImagePath = "";
        /// <summary>
        /// 初始化摄像头
        /// </summary>
        /// <param name="handle">控件句柄</param>
        /// <param name="left"></param>
        /// <param name="top"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public WebCamControl(IntPtr handle, int left, int top, int width, int height)
        {
            mControlPtr = handle;
            mLeft = left;
            mTop = top;
            mWidth = width;
            mHeight = height;
        }
        [Browsable(true), Category("自定义属性"), Description("视频窗口左边距")]
        public int CamLeft
        {
            get { return mLeft; }
            set { mLeft = value; }
        }
        [Browsable(true), Category("自定义属性"), Description("视频窗口右边距")]
        public int CamTop
        {
            get
            {
                return mTop;
            }
            set
            {
                mTop = value;
            }
        }
        [Browsable(true), Category("自定义属性"), Description("视频窗口宽度")]
        public int CamWidth
        {
            set
            {
                mWidth = value;
            }
            get
            {
                return mWidth;
            }
        }
        [Browsable(true), Category("自定义属性"), Description("视频窗口高度")]
        public int CamHeight
        {
            set
            {
                mHeight = value;
            }
            get
            {
                return mHeight;
            }
        }
        /// <summary>
        /// 截图存放路径(bmp格式)
        /// </summary>
        [Browsable(true), Category("自定义属性"), Description("保存截图的文件名")]
        public string GrabImagePath
        {
            get
            {
                return grabImagePath;
            }
            set
            {
                grabImagePath = value;
            }
        }
        string kinescopePath;
        /// <summary>
        /// 录像存放路径(avi格式)
        /// </summary>
        [Browsable(true), Category("自定义属性"), Description("保存录像的文件名(视频格式为.avi)")]
        public string KinescopePath
        {
            get
            {
                return kinescopePath;
            }
            set
            {
                kinescopePath = value;
            }
        }
        private void btnOpen_Click(object sender, EventArgs e)
        {
            if (btnOpen.Text.Equals("开启相机"))
            {
                if (!IsOpen)
                {
                    Start();
                }
            }
            else
            {
                if (IsOpen)
                {
                    Stop();
                }
            }
            if (IsOpen)
            {
                btnOpen.Text = "关闭相机";
                btnOpen.BackColor = Color.LightGreen;
                btnGrabImage.Enabled = true;
                btnKinescope.Enabled = true;
            }
            else
            {
                btnOpen.Text = "开启相机";
                btnOpen.BackColor = Color.Red;
                btnGrabImage.Enabled = false;
                btnKinescope.Enabled = false;
            }
        }
        private void btnGrabImage_Click(object sender, EventArgs e)
        {
            //判断临时文件是否存在
            string tempDir = Path.Combine(Path.GetTempPath(), "WebCam");
            if (!Directory.Exists(tempDir))
            {
                Directory.CreateDirectory(tempDir);
            }
            //生成临时文件名
            string tempFileName = Path.Combine(tempDir, $"{DateTime.Now.ToString("HHmmss")}.bmp");
            GrabImagePath = tempFileName;
            GrabImage();
            GrabImageCompleted?.BeginInvoke(GrabImagePath, null, null);
        }
        private void btnKinescope_Click(object sender, EventArgs e)
        {
            if (btnKinescope.Text.Equals("录像"))
            {
                //判断临时文件是否存在
                string tempDir = Path.Combine(Path.GetTempPath(), "WebCam");
                if (!Directory.Exists(tempDir))
                {
                    Directory.CreateDirectory(tempDir);
                }
                //生成临时文件名
                string tempFileName = Path.Combine(tempDir, $"{DateTime.Now.ToString("HHmmss")}.avi");
                KinescopePath = tempFileName;
                Task.Run(() =>
                {
                    Kinescope();
                });
                btnKinescope.Text = "停止录像";
                btnKinescope.BackColor = Color.LightSeaGreen;
                StartKinescope?.Invoke(this, null);
            }
            else
            {
                StopKinescope();
                KinescopeCompleted?.BeginInvoke(KinescopePath, null, null);
                btnKinescope.Text = "录像";
                btnKinescope.BackColor = Color.Red;
            }
        }
        /// <summary>
        /// 启动摄像头
        /// </summary>
        public void Start()
        {
            if (bStat)
                return;
            bStat = true;
            byte[] lpszName = new byte[100];
            hWndc = capCreateCaptureWindowA(lpszName, WS_CHILD | WS_VISIBLE, mLeft, mTop, mWidth, mHeight, mControlPtr, 0);
            bool flag = false;
            if (hWndc.ToInt32() != 0)
            {
                SendMessage(hWndc, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);
                SendMessage(hWndc, WM_CAP_SET_CALLBACK_ERROR, 0, 0);
                SendMessage(hWndc, WM_CAP_SET_CALLBACK_STATUSA, 0, 0);
                while (true)
                {
                    flag = SendMessage(hWndc, WM_CAP_DRIVER_CONNECT, 0, 0);
                    if (flag) break;
                }
                SendMessage(hWndc, WM_CAP_SET_SCALE, 1, 0);
                SendMessage(hWndc, WM_CAP_SET_PREVIEWRATE, 66, 0);
                SendMessage(hWndc, WM_CAP_SET_OVERLAY, 1, 0);
                SendMessage(hWndc, WM_CAP_SET_PREVIEW, 1, 0);
            }
            return;
        }
        /// <summary>
        /// 停止摄像
        /// </summary>
        public void Stop()
        {
            SendMessage(hWndc, WM_CAP_DRIVER_DISCONNECT, 0, 0);
            bStat = false;
        }
        /// <summary>
        /// 抓图并保存为bmp文件
        /// </summary>
        public void GrabImage()
        {
            IntPtr hBmp = Marshal.StringToHGlobalAnsi(GrabImagePath);
            SendMessage(hWndc, WM_CAP_SAVEDIB, 0, hBmp.ToInt32());
        }
        /// <summary>
        /// 录像(格式为avi)
        /// </summary>
        public void Kinescope()
        {
            IntPtr hBmp = Marshal.StringToHGlobalAnsi(KinescopePath);
            SendMessage(hWndc, WM_CAP_FILE_SET_CAPTURE_FILEA, 0, hBmp.ToInt32());
            SendMessage(hWndc, WM_CAP_SEQUENCE, 0, 0);
        }
        /// <summary>
        /// 将摄像头一帧数据存放在剪切板上
        /// </summary>
        public void CapturePicture()
        {
            SendMessage(hWndc, WM_CAP_SET_PREVIEWRATE, 125, 0);
            SendMessage(hWndc, WM_CAP_SET_EDIT_COPY, 0, 0);
        }
        /// <summary>
        /// 停止录像
        /// </summary>
        public void StopKinescope()
        {
            SendMessage(hWndc, WM_CAP_STOP, 0, 0);
        }
        /// <summary>
        /// 创建一个视频捕捉窗口
        /// </summary>
        /// <param name="lpszWindowsName">标识窗口的名字</param>
        /// <param name="dwStyle">标识窗口的风格</param>
        /// <param name="x">标识窗口的左上角x点</param>
        /// <param name="y">标识窗口的左上角y点</param>
        /// <param name="nWidth">标识窗口的宽度</param>
        /// <param name="nHeight">标识窗口的高度</param>
        /// <param name="hWndParent">标识父窗口句柄</param>
        /// <param name="nID">标识窗口ID</param>
        /// <returns>视频捕捉窗口句柄</returns>
        [DllImport("avicap32.dll")]
        static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowsName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);
        [DllImport("avicap32.dll")]
        static extern int capGetVideoFormat(IntPtr hWnd, IntPtr psVideoFormat, int wSize);
        /// <summary>
        /// 向windows系统发送消息
        /// </summary>
        /// <param name="hWhd">窗口句柄</param>
        /// <param name="msg">发送的消息</param>
        /// <param name="wParam">消息参数</param>
        /// <param name="lParam">消息参数</param>
        /// <returns></returns>
        [DllImport("User32.dll")]
        static extern bool SendMessage(IntPtr hWhd, int msg, int wParam, int lParam);
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值