using GxIAPINET; using HalconDotNet; using Rs.Framework; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace Rs.Cameras { public class DaHengCameras { private static DaHengCameras instance; public static DaHengCameras Instance { get { if (instance == null) instance = new DaHengCameras(); return instance; } } private DaHengCameras() { } List cameraInfos = new List(); public List Init() { IGXFactory.GetInstance().Init(); List infos = new List(); IGXFactory.GetInstance().UpdateAllDeviceList(1000, infos); if(infos!=null && infos.Count>0) { foreach (IGXDeviceInfo devInfo in infos) { try { string userID = string.Empty; userID = devInfo.GetUserID(); if(!string.IsNullOrEmpty(userID)) { IGXDevice dev = IGXFactory.GetInstance().OpenDeviceByUserID(userID, GX_ACCESS_MODE.GX_ACCESS_EXCLUSIVE); IGXFeatureControl featureControl = dev.GetRemoteFeatureControl(); IGXStream stream = dev.OpenStream(0); IGXFeatureControl streamFeatureControl = stream.GetFeatureControl(); GX_DEVICE_CLASS_LIST objDeviceClass = dev.GetDeviceInfo().GetDeviceClass(); if (GX_DEVICE_CLASS_LIST.GX_DEVICE_CLASS_GEV == objDeviceClass) { // 判断设备是否支持流通道数据包功能 if (true == featureControl.IsImplemented("GevSCPSPacketSize")) { // 获取当前网络环境的最优包长值 uint nPacketSize = stream.GetOptimalPacketSize(); // 将最优包长值设置为当前设备的流通道包长值 featureControl.GetIntFeature("GevSCPSPacketSize").SetValue(nPacketSize); } } featureControl.GetEnumFeature("AcquisitionMode").SetValue("Continuous"); //m_objIGXStreamFeatureControl = stream.GetFeatureControl(); DaHengCameraInfo camInfo = new DaHengCameraInfo(userID, dev, featureControl, stream, streamFeatureControl); cameraInfos.Add(camInfo); camInfo.SetTrigger(ETriggerSource.Line0); camInfo.SetExposure(50); camInfo.SetGain(10); camInfo.StartGrabbing(); MessageQueue.Instance.Insert($"Camera {userID} opened success"); } } catch (Exception ex) { MessageQueue.Instance.Warn(ex.Message); } } } else { LogHelper.Debug($"cann't find camera"); } return cameraInfos; } /// /// 根据相机名称获取相机 /// /// /// public DaHengCameraInfo GetCameraInfo(string cameraName) { return cameraInfos.Where(c => c.CameraName == cameraName).FirstOrDefault(); } /// /// 获取所有的相机 /// /// public List GetAllCameras() { return cameraInfos; } public void Deinit() { foreach (DaHengCameraInfo ci in cameraInfos) { ci.Deinit(); } } } /// /// 相机信息 /// public class DaHengCameraInfo { public IGXDevice Camera { get; set; } /// /// 属性控制 /// IGXFeatureControl featureControl; IGXStream stream; IGXFeatureControl streamFeatureControl; public string CameraName { get; set; } public int Index { get; set; } private List Images; public event Action OnImageLoaded; public DaHengCameraInfo(string userID,IGXDevice _dev, IGXFeatureControl _featureControl, IGXStream _stream, IGXFeatureControl _streamFeatureControl) { CameraName = userID; this.Camera = _dev; this.featureControl = _featureControl; this.stream = _stream; streamFeatureControl = _streamFeatureControl; Images = new List(); } public void Deinit() { if (Camera != null) { featureControl.GetCommandFeature("AcquisitionStop").Execute(); stream.StopGrab(); //注销采集回调函数 // m_objIGXStream.UnregisterCaptureCallback(); stream.Close(); stream = null; featureControl = null; Camera.Close(); } } /// /// 清除内存中的图片 /// public void ClearImage() { lock (this) { if (Images != null) { Images.Clear(); } } } /// /// 取图 /// /// public void Grab() { if (Camera != null) { featureControl.GetCommandFeature("TriggerSoftware").Execute(); } } public void StartGrabbing() { if (Camera != null && streamFeatureControl!=null && stream!=null) { streamFeatureControl.GetEnumFeature("StreamBufferHandlingMode").SetValue("OldestFirst"); stream.RegisterCaptureCallback(this, CaptureCallbackPro); stream.StartGrab(); featureControl.GetCommandFeature("AcquisitionStart").Execute(); } } /// /// 回调函数,用于获取图像信息和显示图像 /// /// 用户自定义传入参数 /// 图像信息对象 private void CaptureCallbackPro(object objUserParam, IFrameData objIFrameData) { try { TakePicResult result = new TakePicResult(); LogHelper.Debug($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}-> 收到相机数据"); result.TakeTime = DateTime.Now; //string msg = $"{trayNum},{rowNum},{slotNum},{dt.ToString("yyyy-MM-dd HH:mm:ss fff")},{GetTimeStamp(dt,true)}\r\n"; //File.AppendAllText("d://temp/test.csv", msg); HObject image; HOperatorSet.GenEmptyObj(out image); image.Dispose(); HOperatorSet.GenImage1(out image, "byte", objIFrameData.GetWidth(), objIFrameData.GetHeight(), objIFrameData.GetBuffer()); result.SourceImage = image; //HOperatorSet.WriteImage(image, "bmp", 0, $"d://temp//{trayNum}_{rowNum}_{slotNum}"); //HOperatorSet.WriteImage(image, "tiff",0, "d://d"); AddImage(result); //GxSingleCam objGxSingleCam = objUserParam as GxSingleCam; //objGxSingleCam.ImageShowAndSave(objIFrameData); } catch (Exception) { } } public void AddImage(TakePicResult result) { lock (this) { Images.Add(result); OnImageLoaded?.Invoke(result); } } /// /// 设置曝光时间 /// /// /// public void SetExposure(double timer) { if (Camera != null && featureControl != null) { featureControl.GetFloatFeature("ExposureTime").SetValue(timer); } } /// /// 设置相机增益 /// /// /// /// public void SetGain(double gain) { if (Camera != null && featureControl != null) { featureControl.GetFloatFeature("Gain").SetValue(gain); } } /// /// 设置相机的触发模式 /// /// /// /// public void SetTrigger(ETriggerSource triggerSource = ETriggerSource.Line0) { if (Camera != null) { if (triggerSource == ETriggerSource.Line0) { featureControl.GetEnumFeature("TriggerMode").SetValue("On"); featureControl.GetEnumFeature("TriggerSource").SetValue(ETriggerSource.Line0.ToString()); featureControl.GetEnumFeature("TriggerActivation").SetValue("RisingEdge"); } else { featureControl.GetEnumFeature("TriggerMode").SetValue("On"); featureControl.GetEnumFeature("TriggerSource").SetValue(ETriggerSource.Software.ToString()); } } } /// /// 设置相机XY方向是否反转 /// /// /// /// /// public int SetReverse(EDir dir = EDir.X, bool reverse = false) { if (Camera != null) { if (dir == EDir.X) { featureControl.GetBoolFeature("ReverseX").SetValue(reverse); } else { featureControl.GetBoolFeature("ReverseY").SetValue(reverse); } } else { return -1; } return 0; } /// /// 获取最后一张图片 /// /// public TakePicResult GetLastImage() { lock (this) { if (Images != null && Images.Count > 0) { return Images[Images.Count - 1]; } return null; } } /// /// 获取所有的图片 /// /// public List GetAllImages() { lock (this) { return Images; } } /// /// 获取图片数量 /// /// public int GetImageCount() { lock (this) { if (Images != null && Images.Count > 0) { return Images.Count; } return 0; } } public static long GetTimeStamp(DateTime dt,bool ismilliseconds = false) { //时间戳 毫秒值 //var time = new DateTimeOffset(DateTime.UtcNow); var time = new DateTimeOffset(dt); var timestamp = 0L; if (ismilliseconds) { timestamp = time.ToUnixTimeMilliseconds(); } else timestamp = time.ToUnixTimeSeconds(); return timestamp; } } /// /// 取图结果类 /// public class TakePicResult { /// /// 原图 /// public HObject SourceImage { get; set; } /// /// 相机返回图片时间 /// public DateTime TakeTime { get; set; } /// /// 二维码 /// public string SN { get; set; } public TakePicResult() { } public TakePicResult(HObject sourceImage, DateTime takeTime) { SourceImage = sourceImage; TakeTime = takeTime; } } }