using PaintDotNet.Camera.TUC; using System; using System.Collections.Generic; using System.Drawing; using System.Threading; using System.Windows.Forms; namespace PaintDotNet.Camera { public class CameraManager { private static CameraManager _instance; protected List m_cameraList = new List(); // The list of cameras object private ICamera m_currentCamera; public static event Action FrameCallback; static event Action ShootCallback; /// /// 当发生相机切换, /// public static event Action OnCameraChanged; private CameraManager() { } /// /// 返回相机数量 /// /// public int CameraCount => m_cameraList.Count; public static CameraManager GetInstance() { if (_instance == null) { _instance = new CameraManager(); _instance.InitManager(); } return _instance; } public static bool IsLive { get { if (CurrentCamera == null) return false; string sn; return CurrentCamera.ReadRegisterData(out sn); } } public static event Action OnCameraDrop; public void CheckDevices() { bool drop = false; for (int i = 0; i < m_cameraList.Count;) { string sn; if (m_cameraList[i].ReadRegisterData(out sn)) { i++; } else { m_cameraList.RemoveAt(i); drop = true; } } if (drop) OnCameraDrop?.Invoke(); } /// /// 返回相机列表 /// public List GetCameraList() { return m_cameraList; } /// /// 返回相机名称列表 /// public List GetCameraNameList() { var list = new List(); m_cameraList.ForEach((c) => list.Add(c.GetName())); return list; } public static ICamera CurrentCamera { get => _instance.m_currentCamera; private set { // CurrentCamera?.Close(); value.Open(); OnCameraChanged?.Invoke(_instance.m_currentCamera, value); _instance.m_currentCamera = value; } } public void InitManager() { Logs.Write("InitManager"); m_cameraList.Clear(); m_cameraList.AddRange(TUCamera.Init()); if (m_cameraList.Count > 0) { CurrentCamera = m_cameraList[0]; } else { _instance.m_currentCamera = new TUCamera(0); } new Thread(PreviewRuntime) { IsBackground = true }.Start(); new Thread(PreviewMonitor) { IsBackground = true }.Start(); } /// /// 设置当前使用相机 /// /// public void SetCurrentCamera(int idx) { CurrentCamera = m_cameraList[idx]; } public void UnInitManager() { Logs.Write("UnInitManager"); Running = false; for (int i = 0; i < m_cameraList.Count; i++) { m_cameraList[i]?.Close(); } m_cameraList.Clear(); TUCamera.UnInit(); } DateTime _timeWaitFrame; bool _waitingFrame; public static Action OnCaptureTimeOut; private void PreviewMonitor() { while (Running) { if (!_waitingFrame) { } else if ((DateTime.Now - _timeWaitFrame).TotalMilliseconds > CurrentCamera.ExposureTime + 1000) { Logs.Write("相机拍摄超时"); _waitingFrame = false; OnCaptureTimeOut?.Invoke(); CurrentCamera?.RepairPreview(); } Thread.Sleep(200); } } private void WaitBegin() { _waitingFrame = true; _timeWaitFrame = DateTime.Now; } private void WaitEnd() { _waitingFrame = false; } bool Running; void PreviewRuntime() { Running = true; while (Running) { if (CurrentCamera == null || !CurrentCamera.IsOpen() || (FrameCallback == null && ShootCallback == null)) { ShootCallback = null; Thread.Sleep(30); continue; } WaitBegin(); var img = CurrentCamera.OneShoot(); WaitEnd(); if (img == null) { Logs.Write("获取图片失败"); continue;//added by songxk } ShootCallback?.Invoke((Bitmap)img?.Clone()); ShootCallback = null; FrameCallback?.Invoke((Bitmap)img?.Clone()); } } public static void Shoot(Action callback) { ShootCallback += callback; } } }