You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

511 lines
18 KiB

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<DeviceItem> list = new List<DeviceItem>();
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<VideoPixelItem> list = new List<VideoPixelItem>();
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<VideoPixelItem> list = new List<VideoPixelItem>();
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<CommonResult> WorkStart(IProgress<CommonRequest> 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<CommonRequest>(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);
}
}
}
}