using Microsoft.Extensions.DependencyInjection; using MvCamCtrl.NET; using MvCamCtrl.NET.CameraParams; using SlnMesnac.Config; using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading; namespace SlnMesnac.Common { public class CCameraHik { #region 单例实现 private static readonly Lazy lazy = new Lazy(() => new CCameraHik()); public static CCameraHik Instance { get { return lazy.Value; } } #endregion public delegate void RefreshCamera(string ip,bool flag); public static event RefreshCamera RefreshCameraEvent; private DebugConfig config = DebugConfig.Instance; /// /// 已经打开的设备集合 /// public static Dictionary m_MyCameras = new Dictionary(); /// /// 枚举到的设备集合 /// List m_ltDeviceList = new List(); Thread m_hReceiveThread1 = null; Thread m_hReceiveThread2 = null; bool m_bGrabbing = false; // 存放照片路径 public string PicturePath = System.Environment.CurrentDirectory + "/picture/"; // ch:用于从驱动获取图像的缓存 | en:Buffer for getting image from driver private static Object BufForDriverLock = new Object(); CImage m_pcImgForDriver = null; // 图像信息 CFrameSpecInfo m_pcImgSpecInfo = null; // 图像的水印信息 UInt32 m_nCurWidth = 0; UInt32 m_nCurHeight = 0; MvGvspPixelType m_emPixelType = MvGvspPixelType.PixelType_Gvsp_Mono8; /// /// 枚举设备 /// public void DeviceListAndStart() { // ch:创建设备列表 | en:Create Device List System.GC.Collect(); //枚举设备 int nRet = CSystem.EnumDevices(CSystem.MV_GIGE_DEVICE | CSystem.MV_USB_DEVICE, ref m_ltDeviceList); if (0 != nRet) { // ShowErrorMsg("Enumerate devices fail!", 0); return; } //打开设备 foreach (CCameraInfo deviceInfo in m_ltDeviceList) { bool flag = OpenDevice(deviceInfo); if(!flag) { // TODO 重连 } } Console.WriteLine("设备数:"+m_ltDeviceList.Count); StartGrab(); } public bool OpenDevice(CCameraInfo device) { try { CCamera item = new CCamera(); int nRet = item.CreateHandle(ref device); if (CErrorDefine.MV_OK != nRet) { return false; } nRet = item.OpenDevice(); if (CErrorDefine.MV_OK != nRet) { item.DestroyHandle(); Console.WriteLine("Device open fail!", nRet); return false; } // ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera) if (device.nTLayerType == CSystem.MV_GIGE_DEVICE) { int nPacketSize = item.GIGE_GetOptimalPacketSize(); if (nPacketSize > 0) { nRet = item.SetIntValue("GevSCPSPacketSize", (uint)nPacketSize); if (nRet != CErrorDefine.MV_OK) { Console.WriteLine("Set Packet Size failed!", nRet); } } } // 设置触发模式 item.SetEnumValue("TriggerMode", (uint)MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON); // ch:触发源设为软触发 | en:Set trigger source as Software item.SetEnumValue("TriggerSource", (uint)MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); // ch:取图前的必要操作步骤 | en:Necessary operation before grab CGigECameraInfo cGigEDeviceInfo = (CGigECameraInfo)device; uint nIp1 = ((cGigEDeviceInfo.nCurrentIp & 0xff000000) >> 24); uint nIp2 = ((cGigEDeviceInfo.nCurrentIp & 0x00ff0000) >> 16); uint nIp3 = ((cGigEDeviceInfo.nCurrentIp & 0x0000ff00) >> 8); uint nIp4 = (cGigEDeviceInfo.nCurrentIp & 0x000000ff); string ip = $"{nIp1}.{nIp2}.{nIp3}.{nIp4}"; Console.WriteLine("DevIP:" + ip); RefreshCameraEvent?.Invoke(ip, true); m_MyCameras.Add(ip, item); Console.WriteLine("open success"); return true; } catch (Exception ex) { Console.WriteLine("open()"+ex.Message); return false; } } // ch:取图前的必要操作步骤 | en:Necessary operation before grab private Int32 NecessaryOperBeforeGrab(CCamera m_MyCamera) { // ch:取图像宽 | en:Get Iamge Width CIntValue pcWidth = new CIntValue(); int nRet = m_MyCamera.GetIntValue("Width", ref pcWidth); if (CErrorDefine.MV_OK != nRet) { //ShowErrorMsg("Get Width Info Fail!", nRet); return nRet; } m_nCurWidth = (UInt32)pcWidth.CurValue; // ch:取图像高 | en:Get Iamge Height CIntValue pcHeight = new CIntValue(); nRet = m_MyCamera.GetIntValue("Height", ref pcHeight); if (CErrorDefine.MV_OK != nRet) { // ShowErrorMsg("Get Height Info Fail!", nRet); return nRet; } m_nCurHeight = (UInt32)pcHeight.CurValue; // ch:取像素格式 | en:Get Pixel Format CEnumValue pcPixelFormat = new CEnumValue(); nRet = m_MyCamera.GetEnumValue("PixelFormat", ref pcPixelFormat); if (CErrorDefine.MV_OK != nRet) { // ShowErrorMsg("Get Pixel Format Fail!", nRet); return nRet; } m_emPixelType = (MvGvspPixelType)pcPixelFormat.CurValue; return CErrorDefine.MV_OK; } public void StartGrab() { m_bGrabbing = true; foreach (KeyValuePair pair in m_MyCameras) { int nRet = NecessaryOperBeforeGrab(pair.Value); if (CErrorDefine.MV_OK != nRet) { // TODO重新销毁打开 return; } if (config.Scanner1IP == pair.Key) { m_hReceiveThread1 = new Thread(() => ReceiveThreadProcess(pair.Key,pair.Value)); m_hReceiveThread1.Start(); // ch:开始采集 | en:Start Grabbing nRet = pair.Value.StartGrabbing(); if (CErrorDefine.MV_OK != nRet) { m_bGrabbing = false; m_hReceiveThread1.Join(); // ShowErrorMsg("Start Grabbing Fail!", nRet); return; } } pair.Value.SetEnumValue("ExposureAuto", 0); nRet = pair.Value.SetFloatValue("ExposureTime", 45000.0f); if (nRet != CErrorDefine.MV_OK) { // ShowErrorMsg("Set Exposure Time Fail!", nRet); } pair.Value.SetEnumValue("GainAuto", 0); nRet = pair.Value.SetFloatValue("Gain", 10.0f); if (nRet != CErrorDefine.MV_OK) { // ShowErrorMsg("Set Gain Fail!", nRet); } nRet = pair.Value.SetFloatValue("AcquisitionFrameRate", 9.4f); if (nRet != CErrorDefine.MV_OK) { // ShowErrorMsg("Set Frame Rate Fail!", nRet); } } } public void StopGrab() { try { m_bGrabbing = false; if (m_hReceiveThread1 != null && m_hReceiveThread1.IsAlive) { m_hReceiveThread1.Join(); // 等待线程结束 } if (m_hReceiveThread2 != null && m_hReceiveThread2.IsAlive) { m_hReceiveThread2.Join(); // 等待线程结束 } foreach (KeyValuePair pair in m_MyCameras) { // ch:停止采集 | en:Stop Grabbing int nRet = pair.Value.StopGrabbing(); if (nRet != CErrorDefine.MV_OK) { Console.WriteLine($"相机{pair.Key} Stop Grabbing Fail!", nRet); } // 销毁句柄 nRet = pair.Value.CloseDevice(); if (nRet != CErrorDefine.MV_OK) { Console.WriteLine($"相机{pair.Key} 关闭设备 Fail!", nRet); } // 销毁句柄 nRet = pair.Value.DestroyHandle(); if (nRet != CErrorDefine.MV_OK) { Console.WriteLine($"相机{pair.Key} 销毁句柄 Fail!", nRet); } } } catch (Exception ex) { Console.WriteLine($"stopGarb异常:" + ex.Message); } } /// /// 箱体码扫码成功以后,触发OCR相机拍照解析 /// /// public bool TriggerGather() { //采集前确保照片文件夹为空,防止照片比对出错 DeleteAllPictures(PicturePath); // 两个相机采集照片 foreach (KeyValuePair pair in m_MyCameras) { // 采集一次 // ch:触发命令 | en:Trigger command int nRet = pair.Value.SetCommandValue("TriggerSoftware"); if (CErrorDefine.MV_OK != nRet) { return false; } } return true; } /// /// 照片接收线程 /// /// /// public void ReceiveThreadProcess(string ip ,CCamera m_MyCamera) { int nRet = CErrorDefine.MV_OK; while (m_bGrabbing) { if (ip == config.Scanner1IP) { Console.WriteLine($"{DateTime.Now} 线程1等待接收数据 -->"); } CFrameout pcFrameInfo = new CFrameout(); CDisplayFrameInfo pcDisplayInfo = new CDisplayFrameInfo(); CPixelConvertParam pcConvertParam = new CPixelConvertParam(); nRet = m_MyCamera.GetImageBuffer(ref pcFrameInfo, 1000); if (CErrorDefine.MV_OK == nRet) { lock (BufForDriverLock) { if (null != m_pcImgForDriver) { m_pcImgForDriver.Destory(); m_pcImgForDriver = null; } m_pcImgForDriver = pcFrameInfo.Image.Clone() as CImage; m_pcImgSpecInfo = pcFrameInfo.FrameSpec; } pcDisplayInfo.Image = pcFrameInfo.Image; SaveAndChangeJpg(ip,m_MyCamera); m_MyCamera.FreeImageBuffer(ref pcFrameInfo); } } } /// /// 保存照片,OCR解析,删除照片 /// /// /// private void SaveAndChangeJpg(string ip,CCamera m_MyCamera) { string testPath = PicturePath + "3.jpg"; CSaveImgToFileParam stSaveFileParam = new CSaveImgToFileParam(); lock (BufForDriverLock) { if (null == m_pcImgForDriver || 0 == m_pcImgForDriver.FrameLen) { return; } stSaveFileParam.ImageType = MV_SAVE_IAMGE_TYPE.MV_IMAGE_JPEG; stSaveFileParam.Image = m_pcImgForDriver; stSaveFileParam.Quality = 80; stSaveFileParam.MethodValue = 2; stSaveFileParam.ImagePath = PicturePath + $"photo_{ip}.jpg"; int nRet = m_MyCamera.SaveImageToFile(ref stSaveFileParam); if (CErrorDefine.MV_OK != nRet) { Console.WriteLine("保存照片失败"); return; } } } // 删除指定文件里的照片 private void DeletePhoto(string filePath) { try { // Check if the file exists if (File.Exists(filePath)) { // Delete the file File.Delete(filePath); Console.WriteLine("Photo deleted successfully."); } else { Console.WriteLine("File does not exist."); } } catch (Exception ex) { Console.WriteLine("Error deleting photo: " + ex.Message); } } /// /// 删除文件夹所有照片 /// /// static void DeleteAllPictures(string path) { try { // 检查照片路径是否存在 if (Directory.Exists(path)) { // 获取文件夹中的所有文件 string[] files = Directory.GetFiles(path); // 遍历文件并删除 foreach (string file in files) { File.Delete(file); Console.WriteLine($"Deleted file: {file}"); } Console.WriteLine("All pictures deleted successfully."); } else { Console.WriteLine("无路径"); } } catch (Exception ex) { Console.WriteLine($"DeleteAllPictures异常: {ex.Message}"); } } } }