CameraManager.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. using PaintDotNet.Camera.TUC;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Drawing;
  5. using System.Threading;
  6. using System.Windows.Forms;
  7. namespace PaintDotNet.Camera
  8. {
  9. public class CameraManager
  10. {
  11. private static CameraManager _instance;
  12. protected List<ICamera> m_cameraList = new List<ICamera>(); // The list of cameras object
  13. private ICamera m_currentCamera;
  14. public static event Action<Bitmap> FrameCallback;
  15. static event Action<Bitmap> ShootCallback;
  16. /// <summary>
  17. /// 当发生相机切换,
  18. /// </summary>
  19. public static event Action<ICamera, ICamera> OnCameraChanged;
  20. private CameraManager()
  21. {
  22. }
  23. /// <summary>
  24. /// 返回相机数量
  25. /// </summary>
  26. /// <returns></returns>
  27. public int CameraCount => m_cameraList.Count;
  28. public static CameraManager GetInstance()
  29. {
  30. if (_instance == null)
  31. {
  32. _instance = new CameraManager();
  33. _instance.InitManager();
  34. }
  35. return _instance;
  36. }
  37. public static bool IsLive
  38. {
  39. get
  40. {
  41. if (CurrentCamera == null) return false;
  42. string sn;
  43. return CurrentCamera.ReadRegisterData(out sn);
  44. }
  45. }
  46. public static event Action OnCameraDrop;
  47. public void CheckDevices()
  48. {
  49. bool drop = false;
  50. for (int i = 0; i < m_cameraList.Count;)
  51. {
  52. string sn;
  53. if (m_cameraList[i].ReadRegisterData(out sn))
  54. {
  55. i++;
  56. }
  57. else
  58. {
  59. m_cameraList.RemoveAt(i);
  60. drop = true;
  61. }
  62. }
  63. if (drop)
  64. OnCameraDrop?.Invoke();
  65. }
  66. /// <summary>
  67. /// 返回相机列表
  68. /// </summary>
  69. public List<ICamera> GetCameraList()
  70. {
  71. return m_cameraList;
  72. }
  73. /// <summary>
  74. /// 返回相机名称列表
  75. /// </summary>
  76. public List<string> GetCameraNameList()
  77. {
  78. var list = new List<string>();
  79. m_cameraList.ForEach((c) => list.Add(c.GetName()));
  80. return list;
  81. }
  82. public static ICamera CurrentCamera
  83. {
  84. get => _instance.m_currentCamera;
  85. private set
  86. {
  87. // CurrentCamera?.Close();
  88. value.Open();
  89. OnCameraChanged?.Invoke(_instance.m_currentCamera, value);
  90. _instance.m_currentCamera = value;
  91. }
  92. }
  93. public void InitManager()
  94. {
  95. Logs.Write("InitManager");
  96. m_cameraList.Clear();
  97. m_cameraList.AddRange(TUCamera.Init());
  98. if (m_cameraList.Count > 0)
  99. {
  100. CurrentCamera = m_cameraList[0];
  101. }
  102. else
  103. {
  104. _instance.m_currentCamera = new TUCamera(0);
  105. }
  106. new Thread(PreviewRuntime) { IsBackground = true }.Start();
  107. new Thread(PreviewMonitor) { IsBackground = true }.Start();
  108. }
  109. /// <summary>
  110. /// 设置当前使用相机
  111. /// </summary>
  112. /// <param name="idx"></param>
  113. public void SetCurrentCamera(int idx)
  114. {
  115. CurrentCamera = m_cameraList[idx];
  116. }
  117. public void UnInitManager()
  118. {
  119. Logs.Write("UnInitManager");
  120. Running = false;
  121. for (int i = 0; i < m_cameraList.Count; i++)
  122. {
  123. m_cameraList[i]?.Close();
  124. }
  125. m_cameraList.Clear();
  126. TUCamera.UnInit();
  127. }
  128. DateTime _timeWaitFrame;
  129. bool _waitingFrame;
  130. public static Action OnCaptureTimeOut;
  131. private void PreviewMonitor()
  132. {
  133. while (Running)
  134. {
  135. if (!_waitingFrame)
  136. { }
  137. else if ((DateTime.Now - _timeWaitFrame).TotalMilliseconds > CurrentCamera.ExposureTime + 1000)
  138. {
  139. Logs.Write("相机拍摄超时");
  140. _waitingFrame = false;
  141. OnCaptureTimeOut?.Invoke();
  142. CurrentCamera?.RepairPreview();
  143. }
  144. Thread.Sleep(200);
  145. }
  146. }
  147. private void WaitBegin()
  148. {
  149. _waitingFrame = true;
  150. _timeWaitFrame = DateTime.Now;
  151. }
  152. private void WaitEnd()
  153. {
  154. _waitingFrame = false;
  155. }
  156. bool Running;
  157. void PreviewRuntime()
  158. {
  159. Running = true;
  160. while (Running)
  161. {
  162. if (CurrentCamera == null || !CurrentCamera.IsOpen() || (FrameCallback == null && ShootCallback == null))
  163. {
  164. ShootCallback = null;
  165. Thread.Sleep(30); continue;
  166. }
  167. WaitBegin();
  168. var img = CurrentCamera.OneShoot();
  169. WaitEnd();
  170. if (img == null)
  171. {
  172. Logs.Write("获取图片失败");
  173. continue;//added by songxk
  174. }
  175. ShootCallback?.Invoke((Bitmap)img?.Clone());
  176. ShootCallback = null;
  177. FrameCallback?.Invoke((Bitmap)img?.Clone());
  178. }
  179. }
  180. public static void Shoot(Action<Bitmap> callback)
  181. {
  182. ShootCallback += callback;
  183. }
  184. }
  185. }