2013/8/26

[C#] 使用WebCam 錄影(Record video)&拍照(Take picture)


之前的文章講到如何取得WebCam影像
現在我做了些修正,加入了錄影(Record video)&拍照(Take picture)的功能



首先我使用Timer 替換掉之前的 Application_Idle 的Function
原因是使用原本的Application_Idle在錄影的過程中
畫面上PictureBox不會跟著更新

private void TimerEventProcessor(object sender, EventArgs e)
        {
            Image<Bgr, Byte> frame = cap.QueryFrame(); // Query 攝影機的畫面

            pictureBox1.Image = frame.ToBitmap(); // 把畫面轉換成bitmap型態,在丟給pictureBox元件

            //錄影模式
            if (_isRecording)
            {
                //將影格寫入影片中
                video.WriteFrame<Bgr, byte>(frame);
            }
        }

之前的範例一開始就會自動啟動WebCam
只有顯示影像的功能
但是這次的範例就有三個功能(顯示影像、錄影、拍照)
都會去初始化攝影機,所以就抽出來寫成一個Function

        /// <summary>
        /// 開啟攝影機
        /// </summary>
        private void openWebCam()
        {
            //如果webcam沒啟動
            if (cap == null)
            {
                try
                {
                    //打開預設的webcam
                    cap = new Capture();
                }
                catch (NullReferenceException excpt)
                {
                    MessageBox.Show(excpt.Message);
                }
            }
        
        }

顯示影像的功能跟上個範例差別不大
只是多了按鈕去觸發而已

        private void button1_Click(object sender, EventArgs e)
        {
            openWebCam();

            //webcam啟動
            if (cap != null)
            {
                //frame啟動
                if (_captureInProgress)
                {
                    //stop the capture
                    _captureInProgress = false;
                    button1.Text = "開啟";
                    _timer.Stop();
                }
                //frame關閉
                else
                {
                    //start the capture
                    _captureInProgress = true;
                    button1.Text = "關閉";
                    _timer.Start();
                }
            }
        }

接著是在畫面新加入錄影和停止的按鈕
錄影的觸發事件一開始就是啟動Timer
決定好存放路徑跟檔名
New 一個 Video Object 出來
將_isRecording的Flag 設為True
這樣在Timer 裡面就會把擷取到影格寫入影片檔中

        private void button2_Click(object sender, EventArgs e)
        {
                openWebCam();

                _timer.Start();

                _fileName = string.Format("{0}{1}{2}", _movieDirectory, DateTime.Now.ToString("yyyyMMddHmmss"), ".avi");

                //cap.Width 取得攝影機可支援的最大寬度
                //cap.Height 取得攝影機可支援的最大高度
                video = new VideoWriter(_fileName, 0, 10, cap.Width, cap.Height, true);

                //開啟錄影模式
                _isRecording = true;

        }

當按下停止時
將_isRecording的Flag 設為False
Timer就不會再寫入影片了
這樣簡單就完成影片的製作了

private void button3_Click(object sender, EventArgs e)
        {            
            //錄影完需將影像停止不然會出錯
            _isRecording = false;
            video.Dispose();

        }

拍照功能也很簡單
先在畫面拉一個拍照的按鈕
決定好存放路徑跟檔名
呼叫Image的Save Function
也是輕鬆完成拍照的功能

        //拍攝照片
        private void button4_Click(object sender, EventArgs e)
        {
            openWebCam();

            // Query 攝影機的畫面
            Image<Bgr, Byte> phtoFrame = cap.QueryFrame();

            //儲存路徑
            _fileName = string.Format("{0}{1}{2}", _phtoDirectory, DateTime.Now.ToString("yyyyMMddHmmss"), ".JPG");

            //儲存影像
            phtoFrame.Save(_fileName);
        }

忘了說兩個變數
一個是影片的存放位置
一個是照片的存放位置

        string _movieDirectory = @"d:\Test\movies\";
        string _phtoDirectory = @"d:\Test\photos\";

因為偷懶沒有自動建立資料夾的程式,想用的人可能自己建喔

DEMO

沒有留言:

張貼留言