diff --git a/Rs.Cameras/BaseCamera.cs b/Rs.Cameras/BaseCamera.cs
new file mode 100644
index 0000000..aaba166
--- /dev/null
+++ b/Rs.Cameras/BaseCamera.cs
@@ -0,0 +1,271 @@
+using HalconDotNet;
+using MvCamCtrl.NET;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Rs.Cameras
+{
+ ///
+ /// 方向
+ ///
+ public enum EDir
+ {
+ X,
+ Y
+ }
+
+ public enum ETriggerSource
+ {
+ ///
+ /// 硬触发
+ ///
+ Line0,
+ ///
+ /// 软触发
+ ///
+ Software
+ }
+
+ public abstract class BaseCameraInfo
+ {
+ public MyCamera Camera { get; set; }
+ public string CameraName { get; set; }
+
+ public int Index { get; set; }
+
+ private List Images;
+
+ int apiResult = -1;
+
+ public BaseCameraInfo()
+ {
+ Images = new List();
+ }
+
+ public void Deinit()
+ {
+ if (Camera != null)
+ {
+ Camera.MV_CC_CloseDevice_NET();
+ Camera.MV_CC_DestroyDevice_NET();
+ }
+ }
+ ///
+ /// 清除内存中的图片
+ ///
+ public void ClearImage()
+ {
+ lock (this)
+ {
+ if (Images != null)
+ {
+ Images.Clear();
+ }
+ }
+
+ }
+
+ ///
+ /// 取图
+ ///
+ ///
+ public int Grab()
+ {
+ if (Camera != null)
+ return Camera.MV_CC_SetCommandValue_NET("TriggerSoftware");
+ return -1;
+ }
+
+ public int StartGrabbing()
+ {
+ if (Camera != null)
+ return Camera.MV_CC_StartGrabbing_NET();
+ return -1;
+ }
+
+ public void AddImage(HObject image)
+ {
+ lock (this)
+ {
+ Images.Add(image);
+ }
+
+ }
+
+ ///
+ /// 设置曝光时间
+ ///
+ ///
+ ///
+ public int SetExposure(float timer)
+ {
+ if (Camera != null)
+ {
+ apiResult = Camera.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
+ if (apiResult != 0)
+ {
+
+ return apiResult;
+ }
+ apiResult = Camera.MV_CC_SetFloatValue_NET("ExposureTime", timer);
+ if (apiResult != 0)
+ {
+ return apiResult;
+ }
+ }
+ else
+ {
+ return -1;
+ }
+ return 0;
+ }
+
+ ///
+ /// 设置相机增益
+ ///
+ ///
+ ///
+ ///
+ public int SetGain(float gain)
+ {
+ if (Camera != null)
+ {
+ apiResult = Camera.MV_CC_SetEnumValue_NET("GainAuto", 0);
+ if (apiResult != 0)
+ {
+ return apiResult;
+ }
+ apiResult = Camera.MV_CC_SetFloatValue_NET("Gain", gain);
+ if (apiResult != 0)
+ {
+ return apiResult;
+ }
+ }
+ else
+ {
+ return -1;
+ }
+ return 0;
+ }
+
+ ///
+ /// 设置相机的触发模式
+ ///
+ ///
+ ///
+ ///
+ public int SetTrigger(ETriggerSource triggerSource = ETriggerSource.Line0)
+ {
+ if (Camera != null)
+ {
+ if (triggerSource == ETriggerSource.Line0)
+ {
+ apiResult = Camera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0);
+ if (apiResult != 0)
+ {
+ apiResult = Camera.MV_CC_SetEnumValue_NET("TriggerActivation", 0);//设置上升沿触发
+ if (apiResult != 0)
+ {
+ return apiResult;
+ }
+ }
+ else
+ {
+ return apiResult;
+ }
+ }
+ else
+ {
+ apiResult = Camera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
+ if (apiResult != 0)
+ {
+ return apiResult;
+ }
+ }
+ }
+ else
+ {
+ return -1;
+ }
+ return 0;
+ }
+
+ ///
+ /// 设置相机XY方向是否反转
+ ///
+ ///
+ ///
+ ///
+ ///
+ public int SetReverse(EDir dir = EDir.X, bool reverse = false)
+ {
+ if (Camera != null)
+ {
+ if (dir == EDir.X)
+ {
+ apiResult = Camera.MV_CC_SetBoolValue_NET("ReverseX", reverse);
+ if (apiResult != 0)
+ return apiResult;
+ }
+ else
+ {
+ apiResult = Camera.MV_CC_SetBoolValue_NET("ReverseY", reverse);
+ if (apiResult != 0)
+ return apiResult;
+ }
+ }
+ else
+ {
+ return -1;
+ }
+ return 0;
+ }
+
+ ///
+ /// 获取最后一张图片
+ ///
+ ///
+ public HObject 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;
+ }
+ }
+ }
+}
diff --git a/Rs.Cameras/DaHengCameras.cs b/Rs.Cameras/DaHengCameras.cs
new file mode 100644
index 0000000..bde357f
--- /dev/null
+++ b/Rs.Cameras/DaHengCameras.cs
@@ -0,0 +1,411 @@
+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;
+ }
+ }
+}
diff --git a/Rs.Cameras/HikCamera.cs b/Rs.Cameras/HikCamera.cs
index ed3cc93..47c3587 100644
--- a/Rs.Cameras/HikCamera.cs
+++ b/Rs.Cameras/HikCamera.cs
@@ -11,26 +11,7 @@ using System.Threading.Tasks;
namespace Rs.Cameras
{
- ///
- /// 方向
- ///
- public enum EDir
- {
- X,
- Y
- }
-
- public enum ETriggerSource
- {
- ///
- /// 硬触发
- ///
- Line0,
- ///
- /// 软触发
- ///
- Software
- }
+
public class HikCameras
{
private static HikCameras instance;
diff --git a/Rs.Cameras/Rs.Cameras.csproj b/Rs.Cameras/Rs.Cameras.csproj
index d302df5..ba0b5db 100644
--- a/Rs.Cameras/Rs.Cameras.csproj
+++ b/Rs.Cameras/Rs.Cameras.csproj
@@ -31,6 +31,9 @@
4
+
+ bin\Debug\GxIAPINET.dll
+
..\Rs.MotionPlat\bin\Debug\halcondotnet.dll
@@ -47,6 +50,8 @@
+
+