using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using AForge; using AForge.Controls; using AForge.Imaging; using AForge.Video; using AForge.Video.DirectShow; using System.Threading; using System.Reflection; using ShenTun.Camera.Common; namespace ShenTun.Camera.AForgeL { public partial class FrmCamera : Form { private string path_current = ""; private string ini_file = ""; private Photo SelectedPhoto = null; private FilterInfoCollection videoDevices; private VideoCaptureDevice videoSource; private Bitmap imgMap; private int MaxPiexl = 0; private int MaxPiexlVideo = 0; private int _capturesTotal; private int _capturesTimes; private string _imageFormat; private Boolean _isAutoConnect = false; public DialogResponse Result { get; set; } public FrmCamera(int capturesTotal, int capturesTimes, string imageFormat, Boolean isAutoConnect) { InitializeComponent(); this._capturesTotal = capturesTotal; this._capturesTimes = capturesTimes; this._imageFormat = imageFormat; this._isAutoConnect = isAutoConnect; SetConfigPath(); } private void SetConfigPath() { path_current = string.Format("{0}\\ShenTun", System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments)); if (!Directory.Exists(path_current)) { Directory.CreateDirectory(path_current); } ini_file = string.Format("{0}\\Camera.ini", path_current); } private void SetFormat() { cmbFormat.ValueMember = "Code"; cmbFormat.DisplayMember = "Name"; cmbFormat.DataSource = Common.GetImageFormatList(); } private void SetCmbDevice() { if (videoDevices.Count == 0) return; string name = ""; List list = new List(); for (int i = 0; i < videoDevices.Count; i++) { name = videoDevices[0].Name; DeviceItem d = new DeviceItem() { Index = i, Name = name, }; list.Add(d); } cmbCamera.DisplayMember = "Name"; cmbCamera.ValueMember = "Index"; cmbCamera.DataSource = list; } private void SetCmbPixelVideo(VideoCapabilities[] _videoCapabilities) { if (_videoCapabilities.Length == 0) return; string text = ""; List list = new List(); for (int i = 0; i < _videoCapabilities.Length; i++) { text = string.Format("{0} x {1}", _videoCapabilities[i].FrameSize.Width, _videoCapabilities[i].FrameSize.Height); VideoPixelItem item = new VideoPixelItem() { Index = i, Text = text, }; list.Add(item); } MaxPiexlVideo = _videoCapabilities.Length - 1; cmbPixelVideo.DataSource = list; cmbPixelVideo.DisplayMember = "Text"; cmbPixelVideo.ValueMember = "Index"; } private void SetCmbPixel(VideoCapabilities[] _videoCapabilities) { if (_videoCapabilities.Length == 0) return; string text = ""; List list = new List(); for (int i = 0; i < _videoCapabilities.Length; i++) { text = string.Format("{0} x {1}", _videoCapabilities[i].FrameSize.Width, _videoCapabilities[i].FrameSize.Height); VideoPixelItem item = new VideoPixelItem() { Index = i, Text = text, }; list.Add(item); } MaxPiexl = _videoCapabilities.Length - 1; cmbPixel.DataSource = list; cmbPixel.DisplayMember = "Text"; cmbPixel.ValueMember = "Index"; } private void setEnabled(bool isEnabled) { btnConnect.Enabled = !isEnabled; cmbCamera.Enabled = !isEnabled; cmbPixelVideo.Enabled = isEnabled; btnDisConnect.Enabled = isEnabled; btnPhotoGraph.Enabled = isEnabled; btnProperty.Enabled = isEnabled; btnMultiPhoto.Enabled = isEnabled; btnClear.Enabled = isEnabled; } private void setInfo(string info) { lbInfoText.Text = info; } private void CameraConn() { videoSource = new VideoCaptureDevice(videoDevices[cmbCamera.SelectedIndex].MonikerString); int index = Convert.ToInt32(cmbPixel.SelectedValue); videoSource.VideoResolution = videoSource.VideoCapabilities[index]; videoSourcePlayer1.VideoSource = videoSource; } private void FrmCamera_Load(object sender, EventArgs e) { setEnabled(false); try { // 枚举所有视频输入设备 videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice); if (videoDevices.Count == 0) throw new ApplicationException(); SetCmbDevice(); cmbCamera.SelectedIndex = 0; var _cameraDevice = new VideoCaptureDevice(videoDevices[0].MonikerString); SetCmbPixelVideo(_cameraDevice.VideoCapabilities); SetCmbPixel(_cameraDevice.SnapshotCapabilities); SetFormat(); Common.GetImageFormatList(); ImgFormatItem item = Common.iList.Where(p => (p.Name.Equals(_imageFormat.ToUpper()))).FirstOrDefault(); cmbFormat.SelectedValue = item.Code; cmbFormat.Enabled = false; int cameraIndex = Convert.ToInt32(IniConfigHelper.ReadSetting(ini_file, "Option", "CameraIndex", "0")); cmbCamera.SelectedValue = cameraIndex; setInfo("设备初始化完成..."); if (_isAutoConnect) btnConnect_Click(null, null); } catch (ApplicationException) { //cmbCamera.Items.Add("没有本地设备"); videoDevices = null; setInfo("没有本地设备..."); } catch (Exception ex) { //cmbCamera.Items.Add("没有本地设备"); videoDevices = null; setInfo("没有本地设备..."); MessageBox.Show("初始化失败:" + ex.Message); } } private void cmbCamera_SelectedValueChanged(object sender, EventArgs e) { try { if (this.cmbCamera.SelectedValue == null) return; if (videoDevices.Count == 0 || videoDevices.Count == 1) return; int index = Convert.ToInt32(this.cmbCamera.SelectedValue); var _cameraDevice = new VideoCaptureDevice(videoDevices[index].MonikerString); SetCmbPixelVideo(_cameraDevice.VideoCapabilities); SetCmbPixel(_cameraDevice.SnapshotCapabilities); } catch (Exception ex) { MessageBox.Show("切换摄像头失败:" + ex.Message); } } private void cmbPixelVideo_SelectedValueChanged(object sender, EventArgs e) { try { if (videoSourcePlayer1.VideoSource == null) return; if (cmbCamera.Enabled) return; VideoCaptureDevice videoSource = (VideoCaptureDevice)videoSourcePlayer1.VideoSource; int index = Convert.ToInt32(cmbPixelVideo.SelectedValue); videoSource.VideoResolution = videoSource.VideoCapabilities[index]; videoSourcePlayer1.VideoSource = videoSource; cmbPixel.SelectedValue = cmbPixelVideo.SelectedValue; } catch (Exception ex) { MessageBox.Show("切换分辨率异常:" + ex.Message); } } private void cmbPixel_SelectedValueChanged(object sender, EventArgs e) { try { if (videoSourcePlayer1.VideoSource == null) return; if (cmbCamera.Enabled) return; VideoCaptureDevice videoSource = (VideoCaptureDevice)videoSourcePlayer1.VideoSource; int index = Convert.ToInt32(cmbPixel.SelectedValue); videoSource.SnapshotResolution = videoSource.SnapshotCapabilities[index]; videoSourcePlayer1.VideoSource = videoSource; if (videoSourcePlayer1.IsRunning) { videoSourcePlayer1.SignalToStop(); videoSourcePlayer1.WaitForStop(); } videoSourcePlayer1.Start(); } catch (Exception ex) { MessageBox.Show("切换分辨率异常:" + ex.Message); } } private void btnConnect_Click(object sender, EventArgs e) { try { CameraConn(); int pixelVideoIndex = Convert.ToInt32(IniConfigHelper.ReadSetting(ini_file, "Option", "PixelVideoIndex", "0")); //激活初始化按钮状态 setEnabled(true); videoSourcePlayer1.Start(); Thread.Sleep(300); cmbPixelVideo.SelectedValue = pixelVideoIndex; setInfo("设备已连接..."); }catch(Exception ex) { MessageBox.Show("连接失败:" + ex.Message); } } private void btnDisConnect_Click(object sender, EventArgs e) { videoSourcePlayer1.SignalToStop(); videoSourcePlayer1.WaitForStop(); setEnabled(false); setInfo("设备已断开..."); } void cs_SelectPhotoInfo(string photoId) { SelectedPhoto = null; foreach (var ctrl in flowLayoutPanel1.Controls) { if (!(ctrl is Photo)) continue; if (((Photo)ctrl).PhotoId != photoId) { if (((Photo)ctrl).Selected == true) { ((Photo)ctrl).Selected = false; ((Photo)ctrl).Refresh(); } }else { SelectedPhoto = ((Photo)ctrl); this.picCurrent.Image = SelectedPhoto.Image; } } } private void btnPhotoGraph_Click(object sender, EventArgs e) { try { if (!videoSourcePlayer1.IsRunning) return; imgMap = this.videoSourcePlayer1.GetCurrentVideoFrame(); Photo photo = new Photo() { Image = imgMap, PhotoId = Guid.NewGuid().ToString(), Size = new Size(40, 40), }; photo.SelecPhotoInfo+=new Photo.SelectedPhoto(cs_SelectPhotoInfo); this.flowLayoutPanel1.Controls.Add(photo); this.picCurrent.Image = photo.Image; /* Button b1 = new Button(); MessageBox.Show(string.Format("H:{0},W:{1}", b1.Size.Height, b1.Size.Width)); this.flowLayoutPanel1.Controls.Add(b1); * * */ } catch (Exception ex) { MessageBox.Show("摄像头异常:" + ex.Message); } } void progressChanged(CommonRequest requset) { string infoTitle = requset.Percentage == 100 ? "任务已完成" : "任务正在处理"; string progress = String.Format("{0},进度【{1}%】", infoTitle, requset.Percentage); this.flowLayoutPanel1.Controls.Add(requset.Photo); this.picCurrent.Image = requset.Photo.Image; setInfo(progress); } void WorkCompleted(CommonResult result) { if (result.Success) { //操作成功的处理 } this.btnMultiPhoto.Enabled = true; } private async Task WorkStart(IProgress progress) { var result = new CommonResult(); for (int i = 0; i < _capturesTotal; i++) { imgMap = this.videoSourcePlayer1.GetCurrentVideoFrame(); Photo photo = new Photo() { Image = imgMap, PhotoId = Guid.NewGuid().ToString(), Size = new Size(40, 40), }; photo.SelecPhotoInfo += new Photo.SelectedPhoto(cs_SelectPhotoInfo); await Task.Delay(_capturesTimes); CommonRequest pro = new CommonRequest { Percentage = i + 1, Photo = photo, }; progressChanged(pro); //progress.Report(pro); //异步窗口不需要在progress对象中进行UI更新 } result.Success = true; return result; } private async void btnMultiPhoto_Click(object sender, EventArgs e) { try { if (videoSourcePlayer1.VideoSource == null) return; this.btnMultiPhoto.Enabled = false; var reporter = new Progress(progressChanged); var result = await this.WorkStart(reporter); this.WorkCompleted(result); } catch (Exception ex) { MessageBox.Show("连拍异常:" + ex.Message); } } private void btnProperty_Click(object sender, EventArgs e) { VideoCaptureDevice videoSource = (VideoCaptureDevice)videoSourcePlayer1.VideoSource; videoSource.DisplayPropertyPage(IntPtr.Zero); } private void btnClear_Click(object sender, EventArgs e) { try { if (this.flowLayoutPanel1.Controls.Count == 0) return; this.flowLayoutPanel1.Controls.Clear(); this.picCurrent.Image = null; } catch (Exception ex) { MessageBox.Show("清空异常:" + ex.Message); } } private void btnSave_Click(object sender, EventArgs e) { try { if(picCurrent.Image==null) { MessageBox.Show("没有获取到图片,请先拍照"); return; } System.Drawing.Image img = picCurrent.Image; Bitmap bmp = (Bitmap)img; System.Drawing.Imaging.ImageFormat format = (ImageFormat)cmbFormat.SelectedValue; string extenName = Common.GetImageFormatString(format).ToLower(); string fileName = string.Format("{0}\\{1}.{2}", path_current, "photo", extenName); ImageCodecInfo Encoder = ImageHelper.GetEncoder(format); System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality; EncoderParameters myEncoderParameters = new EncoderParameters(1); EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 50L); myEncoderParameters.Param[0] = myEncoderParameter; bmp.Save(fileName, Encoder, myEncoderParameters); System.Drawing.Image imge = System.Drawing.Image.FromFile(fileName); PhotoResponse resPhoto = new PhotoResponse() { Photo = ImageHelper.ConvertImageToBase64(imge), PhotoFormat = extenName, }; DialogResponse response = new DialogResponse() { code = 1, message = "Success", data = resPhoto, }; Result = response; this.DialogResult = System.Windows.Forms.DialogResult.OK; } catch (Exception ex) { MessageBox.Show("保存异常:" + ex.Message); } } private void FrmCamera_FormClosed(object sender, FormClosedEventArgs e) { try { if (videoSourcePlayer1.IsRunning) { videoSourcePlayer1.SignalToStop(); videoSourcePlayer1.WaitForStop(); } if (cmbCamera.SelectedValue != null) { IniConfigHelper.WriteSetting(ini_file, "Option", "CameraIndex", cmbCamera.SelectedValue.ToString()); IniConfigHelper.WriteSetting(ini_file, "Option", "PixelVideoIndex", cmbPixelVideo.SelectedValue.ToString()); } if(Result==null) { DialogResponse response = new DialogResponse() { code = 0, message = "用户取消操作", }; Result = response; } } catch (Exception ex) { MessageBox.Show("关闭异常:" + ex.Message); } } private void btnCancel_Click(object sender, EventArgs e) { try { DialogResponse response = new DialogResponse() { code = 0, message = "用户取消操作", }; Result = response; this.DialogResult = System.Windows.Forms.DialogResult.Cancel; } catch (Exception ex) { MessageBox.Show("清空异常:" + ex.Message); } } } }