WebCamera.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Windows.Forms;
  5. using AForge.Video;
  6. using AForge.Video.DirectShow;
  7. using AForge.Controls;
  8. using System.Threading;
  9. namespace SHJX.Service.Common.Camera
  10. {
  11. public class WebCamera
  12. {
  13. #region privates fields
  14. public VideoCaptureDevice vidCapDevice { get; set; }
  15. private VideoSourcePlayer vidPlayer { get; set; }
  16. private Bitmap _currFrame;
  17. #endregion
  18. #region static
  19. static FilterInfoCollection vidCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);
  20. public static int GetCameraCounts()
  21. {
  22. return vidCollection.Count;
  23. }
  24. public static string GetCameraMoniker(int index)
  25. {
  26. return vidCollection[index].MonikerString;
  27. }
  28. public static string GetCameraName(int index)
  29. {
  30. return vidCollection[index].Name;
  31. }
  32. #endregion
  33. #region events properties
  34. /// <summary>
  35. /// 画面刷新事件
  36. /// </summary>
  37. public event NewFrameEventHandler NewFrameEvent;
  38. /// <summary>
  39. /// 当前画面,相机开启时有效
  40. /// </summary>
  41. public Bitmap CurrFrame
  42. {
  43. get => vidCapDevice is not null ? _currFrame.Clone() as Bitmap : null;
  44. protected set
  45. {
  46. _currFrame = value;
  47. }
  48. }
  49. #endregion
  50. #region public methods
  51. /// <summary>
  52. /// 摄像头是否已打开
  53. /// </summary>
  54. public bool IsOpened
  55. {
  56. get
  57. {
  58. bool isOpened = false;
  59. if (vidPlayer == null)
  60. {
  61. return isOpened;
  62. }
  63. if (vidPlayer.InvokeRequired)
  64. {
  65. vidPlayer.Invoke(new Action(() =>
  66. {
  67. isOpened = vidPlayer.IsRunning;
  68. }));
  69. }
  70. else
  71. {
  72. isOpened = vidPlayer.IsRunning;
  73. }
  74. return isOpened;
  75. }
  76. }
  77. /// <summary>
  78. /// 初始化摄像头
  79. /// </summary>
  80. /// <param name="cameraMoniker">摄像头名称</param>
  81. public WebCamera(string cameraMoniker)
  82. {
  83. vidCapDevice = new VideoCaptureDevice(cameraMoniker);
  84. vidCapDevice.NewFrame += GetCurrFrame;
  85. vidPlayer = new VideoSourcePlayer
  86. {
  87. VideoSource = vidCapDevice
  88. };
  89. _currFrame = null;
  90. }
  91. public WebCamera()
  92. {
  93. vidCapDevice = new VideoCaptureDevice();
  94. vidPlayer = new VideoSourcePlayer
  95. {
  96. VideoSource = vidCapDevice
  97. };
  98. _currFrame = null;
  99. }
  100. /// <summary>
  101. /// 连接指定的摄像头,并打开视频信号
  102. /// </summary>
  103. /// <param name="cameraMoniker"></param>
  104. /// <returns></returns>
  105. public bool OpenCamera(string cameraMoniker)
  106. {
  107. this.vidCapDevice.Source = cameraMoniker;
  108. vidCapDevice.NewFrame += this.GetCurrFrame;
  109. this.vidCapDevice.Start();
  110. return this.vidCapDevice.IsRunning;
  111. }
  112. /// <summary>
  113. /// 设置显示摄像头图像区域
  114. /// </summary>
  115. /// <param name="parentControl"></param>
  116. /// <param name="left"></param>
  117. /// <param name="top"></param>
  118. /// <param name="width"></param>
  119. /// <param name="height"></param>
  120. public void ShowControl(ref Panel parentControl, int left, int top, int width, int height)
  121. {
  122. if (vidPlayer == null) return;
  123. parentControl.Controls.Add(vidPlayer);
  124. vidPlayer.Location = new Point(left, top);
  125. vidPlayer.Size = new Size(width, height);
  126. vidPlayer.Visible = true;
  127. }
  128. /// <summary>
  129. /// 显示摄像头属性设置窗体
  130. /// </summary>
  131. /// <param name="parentWindow"></param>
  132. public void ShowProperties(IntPtr parentWindow)
  133. {
  134. vidCapDevice.DisplayPropertyPage(parentWindow);
  135. }
  136. /// <summary>
  137. /// 设置相机属性值
  138. /// </summary>
  139. /// <param name="prop"></param>
  140. /// <param name="val"></param>
  141. /// <param name="flags"></param>
  142. public void SetProperties(CameraControlProperty prop, int val, CameraControlFlags flags)
  143. {
  144. vidCapDevice.SetCameraProperty(prop, val, flags);// 取消自动曝光
  145. }
  146. /// <summary>
  147. /// 读取当前属性值
  148. /// </summary>
  149. /// <param name="prop"></param>
  150. /// <param name="val"></param>
  151. /// <param name="flags"></param>
  152. public void GetProperties(CameraControlProperty prop, out int val, out CameraControlFlags flags)
  153. {
  154. vidCapDevice.GetCameraProperty(prop, out val, out flags);
  155. }
  156. /// <summary>
  157. /// 读取相机参数的取值范围
  158. /// </summary>
  159. /// <param name="prop"></param>
  160. /// <param name="minValue"></param>
  161. /// <param name="maxValue"></param>
  162. /// <param name="stepSize"></param>
  163. /// <param name="defaultValue"></param>
  164. /// <param name="flags"></param>
  165. public void GetPropertiesRange(CameraControlProperty prop, out int minValue, out int maxValue, out int stepSize, out int defaultValue, out CameraControlFlags flags)
  166. {
  167. vidCapDevice.GetCameraPropertyRange(prop, out minValue, out maxValue, out stepSize, out defaultValue, out flags);
  168. }
  169. /// <summary>
  170. /// 设置视频属性值,亮度、对比度、白平衡、增益等
  171. /// </summary>
  172. /// <param name="prop"></param>
  173. /// <param name="val"></param>
  174. /// <param name="flags"></param>
  175. public void SetVideoProcAmpProperties(VideoProcAmpProperty prop, int val, VideoProcAmpFlags flags)
  176. {
  177. vidCapDevice.SetVideoProcAmpProperty(prop, val, flags);
  178. }
  179. /// <summary>
  180. /// 读取当前视频参数
  181. /// </summary>
  182. /// <param name="prop"></param>
  183. /// <param name="val"></param>
  184. /// <param name="flags"></param>
  185. public void GetVideoProcAmpProperties(VideoProcAmpProperty prop, out int val, out VideoProcAmpFlags flags)
  186. {
  187. vidCapDevice.GetVideoProcAmpProperty(prop, out val, out flags);
  188. }
  189. /// <summary>
  190. /// 读取视频参数的取值范围
  191. /// </summary>
  192. /// <param name="prop"></param>
  193. /// <param name="minValue"></param>
  194. /// <param name="maxValue"></param>
  195. /// <param name="stepSize"></param>
  196. /// <param name="defaultValue"></param>
  197. /// <param name="flags"></param>
  198. public void GetVideoProcAmpPropertiesRange(VideoProcAmpProperty prop, out int minValue, out int maxValue, out int stepSize, out int defaultValue, out VideoProcAmpFlags flags)
  199. {
  200. vidCapDevice.GetVideoProcAmpPropertyRange(prop, out minValue, out maxValue, out stepSize, out defaultValue, out flags);
  201. }
  202. /// <summary>
  203. /// 返回视频支持的分辨率
  204. /// </summary>
  205. /// <returns></returns>
  206. public List<string> GetVideoResolution()
  207. {
  208. List<string> resolution = new List<string>();
  209. foreach (var cap in vidCapDevice.VideoCapabilities)
  210. {
  211. resolution.Add(string.Format("{0} x {1}", cap.FrameSize.Width, cap.FrameSize.Height));
  212. }
  213. return resolution;
  214. }
  215. /// <summary>
  216. /// 设定视频的分辨率,index可以通过GetVideoResolution()获取所有支持的分辨率来确定
  217. /// </summary>
  218. /// <param name="index">在所有支持分辨率中的序号</param>
  219. public void SetVideoResolution(int index)
  220. {
  221. if (vidCapDevice.VideoCapabilities.Length > index)
  222. {
  223. vidCapDevice.VideoResolution = vidCapDevice.VideoCapabilities[index];
  224. }
  225. }
  226. /// <summary>
  227. /// 打开摄像头
  228. /// </summary>
  229. /// <returns></returns>
  230. public bool OpenCamera()
  231. {
  232. if (vidCapDevice != null && vidCapDevice.IsRunning == false)
  233. {
  234. vidCapDevice.NewFrame += NewFrameEvent;
  235. vidCapDevice.Start();
  236. }
  237. if (vidPlayer.InvokeRequired)
  238. {
  239. vidPlayer.Invoke(new Action(() =>
  240. {
  241. if (vidPlayer != null && !vidPlayer.IsRunning)
  242. {
  243. vidPlayer.Start();
  244. }
  245. }));
  246. }
  247. else
  248. {
  249. if (vidPlayer != null && !vidPlayer.IsRunning)
  250. {
  251. vidPlayer.Start();
  252. }
  253. }
  254. return true;
  255. }
  256. /// <summary>
  257. /// 关闭摄像头
  258. /// </summary>
  259. public void CloseCamera()
  260. {
  261. if (vidCapDevice != null && vidCapDevice.IsRunning)
  262. {
  263. vidCapDevice.Stop();
  264. vidCapDevice.NewFrame -= NewFrameEvent;
  265. }
  266. if (vidPlayer.InvokeRequired)
  267. {
  268. vidPlayer.Invoke(new Action(() =>
  269. {
  270. if (vidPlayer == null || !vidPlayer.IsRunning) return;
  271. vidPlayer.SignalToStop();
  272. vidPlayer.WaitForStop();
  273. }));
  274. }
  275. else
  276. {
  277. if (vidPlayer == null || !vidPlayer.IsRunning) return;
  278. vidPlayer.SignalToStop();
  279. vidPlayer.WaitForStop();
  280. }
  281. }
  282. /// <summary>
  283. /// 拍照
  284. /// </summary>
  285. /// <returns></returns>
  286. public Bitmap GrabImage()
  287. {
  288. Bitmap bmp = null;
  289. if (vidPlayer.InvokeRequired)
  290. {
  291. vidPlayer.Invoke(new Action(() =>
  292. {
  293. if (vidPlayer.IsRunning)
  294. {
  295. bmp = vidPlayer.GetCurrentVideoFrame();
  296. }
  297. else
  298. {
  299. // 探头未连接,重试
  300. int cnt = 0; // 重试10秒
  301. while (!vidPlayer.IsRunning && cnt < 100)
  302. {
  303. vidPlayer.Start();
  304. Thread.Sleep(100);
  305. cnt++;
  306. //PublicDatas.LogProgram.Error("摄像头未连接,正在重试" + cnt.ToString());
  307. }
  308. Thread.Sleep(300);
  309. bmp = vidPlayer.GetCurrentVideoFrame();
  310. }
  311. }));
  312. }
  313. else
  314. {
  315. if (vidPlayer.IsRunning)
  316. {
  317. bmp = vidPlayer.GetCurrentVideoFrame();
  318. }
  319. else
  320. {
  321. // 探头未连接,重试
  322. int cnt = 0; // 重试10秒
  323. while (!vidPlayer.IsRunning && cnt < 100)
  324. {
  325. vidPlayer.Start();
  326. Thread.Sleep(100);
  327. cnt++;
  328. // PublicDatas.LogProgram.Error("摄像头未连接,正在重试" + cnt.ToString());
  329. }
  330. Thread.Sleep(300);
  331. bmp = vidPlayer.GetCurrentVideoFrame();
  332. }
  333. }
  334. return bmp;
  335. }
  336. /// <summary>
  337. /// 拍照,返回CurrFrame图像
  338. /// </summary>
  339. /// <returns></returns>
  340. public Bitmap GrabImage2()
  341. {
  342. return CurrFrame;
  343. }
  344. /// <summary>
  345. /// 实时将新的画面存入CurrFrame对象中
  346. /// </summary>
  347. /// <param name="sender"></param>
  348. /// <param name="e"></param>
  349. public void GetCurrFrame(object sender, NewFrameEventArgs e)
  350. {
  351. try
  352. {
  353. if (e.Frame != null)
  354. {
  355. CurrFrame = e.Frame;
  356. }
  357. }
  358. catch (Exception)
  359. {
  360. // ignored
  361. }
  362. }
  363. #endregion
  364. }
  365. }