C#操作攝像頭 實現拍照功能
轉自:http://www.cnblogs.com/xsyblogs/p/3551986.html
從正式工作以來一直做的都是基於B/S的Web開發,已經很長時間不研究C/S的東西了,但是受朋友的委託,幫他做一下拍照的這麼個小功能。其實類似的程式碼網上有很多,但是真的能夠拿來執行的估計也沒幾個。本來是說週末給做的,但是這兩天腦子一直很亂,也沒靜下來,晚上了,再不做明天有點不好意思啊,只能臨時做一個了。在網上找資料自己做的過程中也發現了一些問題,於是拿到部落格上來分享一下,這樣一來有需要的朋友可以直接拿來用,二來正在研究的遇到這些問題了可以迎刃而解。
剛開始接觸攝像頭視訊之類的是在大二的時候,那時候因為實驗室有一個小專案交到我手上,所以那時候對播放視訊之類的瞭解了一些。那時候的需求是對已經錄下來的監控錄影做處理,整個過程是已經不需要自己再去控制錄影了,所以相對簡單一點。而拍照和攝像是自己控制,所以稍微複雜那麼一點點。行了,廢話說到這裡,下面進入正題。
還是以往的作風,只實現功能,對介面不做過多的美化,有需要的朋友可以自己動手。比較這年頭自己動手,豐衣足食嘛。圖1-1是程式的主介面:
圖1-1
操作攝像頭以及實現拍照功能整個過程主要都是通過一個第三方的元件實現的,名字叫做 AForge ,是國外的元件,所以開啟起來有點慢,但是要有耐心啊,目前已經更新到2.2.5版本了。如果不願意從官網上下載,文章末尾處也給出了相應的下載地址,需要的話直接拿來用就ok了。程式也很簡單,一個WinForm頁面,新增一下對Aforge的引用就可以了,但是這個過程中會引用一些其他的dll,有些不是太常用,所以在這裡對引用的dll也做了截圖(圖1-2),在自己做的過程中參照一下即可。
圖1-2
上圖1-1中間部分是用來實時顯示攝像頭開啟後獲取到的內容,是一個自定義控制元件。這裡得說明一下,將AForge.Controls.dll拖拽到左側的工具箱區域,然後就出來自定義控制元件了。這裡順便說明一下,我們平時自己開發的自定義控制元件也可以通過這種方式來給別人用。前臺都準備好了之後我們來開始分析後臺程式碼。
整個的思路是先找到電腦上的攝像頭裝置,然後選擇我們需要操作的裝置,然後在拍照或者攝像。今天由於時間關係僅僅只是實現拍照,下次再做攝像的功能,實現之後也會一樣分享在這裡的,希望有需要的朋友關注。
當Form載入的時候,我們監聽一下其Load事件,將檢測到的攝像頭裝置新增到後邊的ComboBox中供使用者選擇,關鍵程式碼如下:
private void Form1_Load(object sender, EventArgs e) { try { // 列舉所有視訊輸入裝置 videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice); if (videoDevices.Count == 0) throw new ApplicationException(); foreach (FilterInfo device in videoDevices) { tscbxCameras.Items.Add(device.Name); } tscbxCameras.SelectedIndex = 0; } catch (ApplicationException) { tscbxCameras.Items.Add("No local capture devices"); videoDevices = null; } }
當用戶選擇某一攝像頭裝置再點選連線的時候,我們開啟攝像頭,並對其進行初始化,關鍵程式碼:
//連線攝像頭 private void CameraConn() { VideoCaptureDevice videoSource = new VideoCaptureDevice(videoDevices[tscbxCameras.SelectedIndex].MonikerString); videoSource.DesiredFrameSize = new System.Drawing.Size(320, 240); videoSource.DesiredFrameRate = 1; videoSourcePlayer.VideoSource = videoSource; videoSourcePlayer.Start(); }
當用戶關閉點選關閉攝像頭的時候,我們做關閉的處理,程式碼:
//關閉攝像頭 private void btnClose_Click(object sender, EventArgs e) { videoSourcePlayer.SignalToStop(); videoSourcePlayer.WaitForStop(); }
當用戶點選拍照的時候,我們獲取攝像頭當前的畫面,並儲存到設定的路徑下,然後關閉當前視窗。關鍵程式碼:
//拍照 private void Photograph_Click(object sender, EventArgs e) { try { if (videoSourcePlayer.IsRunning) { BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( videoSourcePlayer.GetCurrentVideoFrame().GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); PngBitmapEncoder pE = new PngBitmapEncoder(); pE.Frames.Add(BitmapFrame.Create(bitmapSource)); string picName = GetImagePath() + "\\" + "xiaosy" + ".jpg"; if (File.Exists(picName)) { File.Delete(picName); } using (Stream stream = File.Create(picName)) { pE.Save(stream); } //拍照完成後關攝像頭並重新整理同時關窗體 if (videoSourcePlayer != null && videoSourcePlayer.IsRunning) { videoSourcePlayer.SignalToStop(); videoSourcePlayer.WaitForStop(); } this.Close(); } } catch (Exception ex) { MessageBox.Show("攝像頭異常:" + ex.Message); } } private string GetImagePath() { string personImgPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory) + Path.DirectorySeparatorChar.ToString() + "PersonImg"; if (!Directory.Exists(personImgPath)) { Directory.CreateDirectory(personImgPath); } return personImgPath; }
關閉之後,在bin目錄下的PersonImg中即可找到儲存的圖片,當然,在程式中把該圖片展示出來效果會更好,但是由於時間關係,就不添加了。需要的朋友可以自己實現,有問題的歡迎一起交流。
至此,這樣一個簡單的拍照功能就完成了,在這裡,附上原始碼下載地址。
您的支援,是我分享的動力,謝謝!