using MvCamCtrl.NET; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using TeamAAS_VP.Core.Cameras; using TeamAAS_VP.Interfaces; using TeamAAS_VP.Models; namespace TeamAAS_VP.Services { public class CameraService : ICameraService, IDisposable { private readonly Dictionary _CameraCollection; private readonly object _sync = new object(); public CameraService() { _CameraCollection = new Dictionary(); } public bool CreateCamera(Guid id, CameraInfo cameraInfo) { if (cameraInfo == null) throw new ArgumentNullException(nameof(cameraInfo)); var camera = CreateCameraInstance(id, cameraInfo); lock (_sync) { if (_CameraCollection.ContainsKey(id)) { var currenCamera = _CameraCollection[id]; try { currenCamera.CloseDevice(); } catch { // 忽略关闭异常 } } _CameraCollection[id] = camera; } return true; } public Task CreateCameraAsync(Guid id, CameraInfo cameraInfo) { return Task.Run(() => CreateCamera(id, cameraInfo)); } public ICamera GetCamera(Guid id) { lock (_sync) { if (_CameraCollection.TryGetValue(id, out var cam)) return cam; } return null; } public Task GetCameraAsync(Guid id) { return Task.Run(() => { return GetCamera(id); }); } public void UnRegisterCamera(Guid id) { ICamera camera = null; lock (_sync) { if (_CameraCollection.TryGetValue(id, out camera)) { _CameraCollection.Remove(id); } } if (camera != null) { try { camera.CloseDevice(); } catch { // 忽略关闭异常 } } } public Task UnRegisterCameraAsync(Guid id) { return Task.Run(() => UnRegisterCamera(id)); } public IReadOnlyCollection GetAllCameras() { lock (_sync) { return _CameraCollection.Values.ToList().AsReadOnly(); } } public Task> GetAllCamerasAsync() { return Task.Run(() => { return GetAllCameras(); }); } public bool TryGetCamera(Guid id, out ICamera camera) { lock (_sync) { return _CameraCollection.TryGetValue(id, out camera); } } public Task<(bool found, ICamera camera)> TryGetCameraAsync(Guid id) { return Task.Run(() => { ICamera camera; bool found; lock (_sync) { found = _CameraCollection.TryGetValue(id, out camera); } return (found, camera); }); } public bool ContainsCamera(Guid id) { lock (_sync) { return _CameraCollection.ContainsKey(id); } } public Task ContainsCameraAsync(Guid id) { return Task.Run(() => { return ContainsCamera(id); }); } public bool RemoveCamera(Guid id) { ICamera camera = null; lock (_sync) { if (_CameraCollection.TryGetValue(id, out camera)) { _CameraCollection.Remove(id); } } if (camera != null) { try { camera.CloseDevice(); } catch { // 忽略关闭异常 } return true; } return false; } public Task RemoveCameraAsync(Guid id) { return Task.Run(() => { return RemoveCamera(id); }); } public ICamera GetCameraByNumber(int number) { if (TryFindCameraByNumber(number, out _, out var camera)) return camera; return null; } public Task GetCameraByNumberAsync(int number) { return Task.Run(() => { return GetCameraByNumber(number); }); } public Task UnRegisterCameraByNumberAsync(int number) { return Task.Run(() => { UnRegisterCameraByNumber(number); }); } public void UnRegisterCameraByNumber(int number) { if (TryFindCameraByNumber(number, out var id, out var camera)) { UnRegisterCamera(id); } } /// /// 移除所有相机 /// public void RemoveAllCameras() { //依次移除每一个相机,确保资源释放 List cameraIds; lock (_sync) { cameraIds = _CameraCollection.Keys.ToList(); } foreach (var id in cameraIds) { RemoveCamera(id); } } /// /// 初始化所有相机 /// /// /// public (bool IsSucceed, string Message) InitializeAllCameras(CameraInfo[] cameras) { //清除现有相机 RemoveAllCameras(); foreach (var camInfo in cameras) { var camera = CreateCameraInstance(camInfo.Id, camInfo); lock (_sync) { _CameraCollection[camInfo.Id] = camera; } } bool allConnected = true; StringBuilder errorMessages = new StringBuilder(); //获取所有相机并尝试打开设备 foreach (var camInfo in cameras) { if (TryGetCamera(camInfo.Id, out var camera)) { bool opened = camera.OpenDevice(); if (!opened) { allConnected = false; errorMessages.AppendLine($"相机 {camInfo.CameraName}(编号: {camInfo.CameraNo})打开失败: {camera.ErrorMessage}"); } } else { allConnected = false; errorMessages.AppendLine($"未找到相机 {camInfo.CameraName}(编号: {camInfo.CameraNo})的实例。"); } } if (allConnected) { return (true, "所有相机均已成功初始化并连接。"); } else { return (false, errorMessages.ToString()); } } /// /// 初始化所有相机(异步) /// /// /// public Task<(bool IsSucceed, string Message)> InitializeAllCamerasAsync(CameraInfo[] cameras) { return Task.Run(() => InitializeAllCameras(cameras)); } /// /// 更新相机编号 /// /// /// public void UpdateCameraNumber(Guid id, int newNumber) { if (TryGetCamera(id, out var camera)) { camera.Index = newNumber; } } private ICamera CreateCameraInstance(Guid id, CameraInfo cameraInfo) { ICamera camera; if (cameraInfo.CameraBrand == Enums.CameraBrand.Basler_Pylon) { camera = new BaslerCamera(id, cameraInfo.CameraNo, cameraInfo.CameraName, cameraInfo.SerialNumber, cameraInfo.CameraIp, cameraInfo.IsFindByIp); } else if (cameraInfo.CameraBrand == Enums.CameraBrand.HikRobot_MVS) { camera = new MvCamera(id, cameraInfo.CameraNo, cameraInfo.CameraName, cameraInfo.SerialNumber, cameraInfo.CameraIp, cameraInfo.IsFindByIp); } else if (cameraInfo.CameraBrand == Enums.CameraBrand.IRayple) { camera = new AHuaCamera(id, cameraInfo.CameraNo, cameraInfo.CameraName, cameraInfo.SerialNumber, cameraInfo.CameraIp, cameraInfo.IsFindByIp); } else if (cameraInfo.CameraBrand == Enums.CameraBrand.Cognex) { camera = new CognexCamera(id, cameraInfo.CameraNo, cameraInfo.CameraName, cameraInfo.SerialNumber, cameraInfo.CameraIp, cameraInfo.IsFindByIp); } else if (cameraInfo.CameraBrand == Enums.CameraBrand.Galaxy) { camera = new GalaxyCamera(id, cameraInfo.CameraNo, cameraInfo.CameraName, cameraInfo.SerialNumber, cameraInfo.CameraIp, cameraInfo.IsFindByIp); } else { camera = new MvCamera(id, cameraInfo.CameraNo, cameraInfo.CameraName, cameraInfo.SerialNumber, cameraInfo.CameraIp, cameraInfo.IsFindByIp); } return camera; } private bool TryFindCameraByNumber(int number, out Guid id, out ICamera camera) { lock (_sync) { foreach (var kvp in _CameraCollection) { var c = kvp.Value; if (c == null) continue; object rawValue = null; var type = c.GetType(); var prop = type.GetProperty("CameraNo") ?? type.GetProperty("Number") ?? type.GetProperty("No"); if (prop != null) { try { rawValue = prop.GetValue(c); } catch { rawValue = null; } } if (rawValue == null) { var infoProp = type.GetProperty("CameraInfo") ?? type.GetProperty("Info"); if (infoProp != null) { try { var infoObj = infoProp.GetValue(c); if (infoObj != null) { var infoType = infoObj.GetType(); var numberProp = infoType.GetProperty("CameraNo") ?? infoType.GetProperty("CameraNumber") ?? infoType.GetProperty("Number") ?? infoType.GetProperty("No"); if (numberProp != null) { try { rawValue = numberProp.GetValue(infoObj); } catch { rawValue = null; } } } } catch { rawValue = null; } } } if (rawValue != null) { int parsed; try { if (rawValue is int) parsed = (int)rawValue; else parsed = Convert.ToInt32(rawValue); } catch { continue; } if (parsed == number) { id = kvp.Key; camera = c; return true; } } } } id = Guid.Empty; camera = null; return false; } public void Dispose() { List cameras; lock (_sync) { cameras = _CameraCollection.Values.ToList(); _CameraCollection.Clear(); } foreach (var c in cameras) { try { c.CloseDevice(); } catch { // 忽略单个相机关闭异常 } } GC.SuppressFinalize(this); } } }