using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Timers; using System.Windows.Forms; using MvCamCtrl.NET; using Newtonsoft.Json.Linq; using static ControllerDllCSharp.ClassLibControllerDll; namespace ProductionControl.Device { public class Scanner : IDisposable { [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool IsWindow(IntPtr hWnd); public enum ScannerType { [Description("板卡相机")] GENTL = 0, [Description("网口相机")] CC = 1, } private ScannerType scannerType; public Action log; /// /// 拍照回传 (1-num,文件名.bmp) /// public Action ScanEvent; /// /// 曝光 /// public float ExposureTime { get; private set; } /// /// 增益 /// public float Gain { get; private set; } /// /// 帧率 /// public float ResultingFrameRate { get; private set; } /// /// 是否连续模式 /// public bool isContinuousMode { get; private set; } /// /// 是否打开设备成功 /// public bool IsInit { get; private set; } = false; //public string ErrInfo { get; private set; } //private System.Timers.Timer timer = new System.Timers.Timer(); #region private MyCamera.MV_GENTL_DEV_INFO_LIST m_stGentDeviceList = new MyCamera.MV_GENTL_DEV_INFO_LIST(); private MyCamera.MV_GENTL_IF_INFO_LIST m_stIFInfoList = new MyCamera.MV_GENTL_IF_INFO_LIST(); private MyCamera.MV_CC_DEVICE_INFO_LIST m_stCCDeviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST(); private MyCamera m_MyCamera = new MyCamera(); private bool m_bGrabbing = false;//开始采集TAG private Thread m_hReceiveThread = null; //显示图像控件句柄 private IntPtr previewHwnd = IntPtr.Zero; //拍照数量 private int scanNum = 0; #endregion public Scanner(ScannerType type) { this.scannerType = type; } public bool open() { if (IsInit) return true; System.GC.Collect(); int nRet; if (this.scannerType==ScannerType.GENTL) { nRet = MyCamera.MV_CC_EnumInterfacesByGenTL_NET(ref m_stIFInfoList, Config.Scanner_GENTL_CTI); if (0 != nRet || m_stIFInfoList.nInterfaceNum<1) { log?.Invoke(2, $"Enumerate interfaces fail! ({nRet})"); return false; } // MyCamera.MV_GENTL_IF_INFO stIFInfo = (MyCamera.MV_GENTL_IF_INFO)Marshal.PtrToStructure(m_stIFInfoList.pIFInfo[0], typeof(MyCamera.MV_GENTL_IF_INFO)); nRet = MyCamera.MV_CC_EnumDevicesByGenTL_NET(ref stIFInfo, ref m_stGentDeviceList); if (0 != nRet || m_stGentDeviceList.nDeviceNum<1) { log?.Invoke(2, $"Enumerate devices fail! ({nRet})"); return false; } // ch:获取选择的设备信息 | en:Get selected device information MyCamera.MV_GENTL_DEV_INFO device = (MyCamera.MV_GENTL_DEV_INFO)Marshal.PtrToStructure(m_stGentDeviceList.pDeviceInfo[0], typeof(MyCamera.MV_GENTL_DEV_INFO)); // ch:打开设备 | en:Open device if (null == m_MyCamera) { m_MyCamera = new MyCamera(); if (null == m_MyCamera) { log?.Invoke(2, $"Open device fail!"); return false; } } nRet = m_MyCamera.MV_CC_CreateDeviceByGenTL_NET(ref device); if (MyCamera.MV_OK != nRet) { log?.Invoke(2, $"Open device fail! ({nRet})"); return false; } nRet = m_MyCamera.MV_CC_OpenDevice_NET(); if (MyCamera.MV_OK != nRet) { m_MyCamera.MV_CC_DestroyDevice_NET(); log?.Invoke(2, $"Device open fail! ({nRet})"); return false; } } else //CC { nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_stCCDeviceList); if (0 != nRet || m_stCCDeviceList.nDeviceNum<1) { log?.Invoke(2, $"Enumerate devices fail! ({nRet})"); return false; } // ch:获取选择的设备信息 MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_stCCDeviceList.pDeviceInfo[0], typeof(MyCamera.MV_CC_DEVICE_INFO)); // ch:打开设备 | en:Open device if (null == m_MyCamera) { m_MyCamera = new MyCamera(); if (null == m_MyCamera) { log?.Invoke(2, $"Open device fail!"); return false; } } nRet = m_MyCamera.MV_CC_CreateDevice_NET(ref device); if (MyCamera.MV_OK != nRet) { log?.Invoke(2, $"Open device fail! ({nRet})"); return false; } nRet = m_MyCamera.MV_CC_OpenDevice_NET(); if (MyCamera.MV_OK != nRet) { m_MyCamera.MV_CC_DestroyDevice_NET(); log?.Invoke(2, $"Open device fail! ({nRet})"); return false; } // ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera) if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE) { int nPacketSize = m_MyCamera.MV_CC_GetOptimalPacketSize_NET(); if (nPacketSize > 0) { nRet = m_MyCamera.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize); //if (nRet != MyCamera.MV_OK) //{ // ShowErrorMsg("Set Packet Size failed!", nRet); //} } else { //ShowErrorMsg("Get Packet Size failed!", nPacketSize); } } } // ch:设置采集[软触发/连续]模式 | en:Set Continues Aquisition Mode m_MyCamera.MV_CC_SetEnumValue_NET("AcquisitionMode", (uint)MyCamera.MV_CAM_ACQUISITION_MODE.MV_ACQ_MODE_CONTINUOUS); setMode(false); //软触发 // getParam(); IsInit = true; //timer.Elapsed += Timer_Elapsed; //timer.Interval = 100; //timer.Enabled = true; return true; } public void close() { if (!IsInit) return; IsInit = false; // ch:取流标志位清零 | en:Reset flow flag bit if (m_bGrabbing == true) { m_bGrabbing = false; m_hReceiveThread.Join(); } // ch:关闭设备 | en:Close Device m_MyCamera.MV_CC_CloseDevice_NET(); m_MyCamera.MV_CC_DestroyDevice_NET(); } /// /// /// /// 显示图像控件句柄 /// public bool start(IntPtr preview_Hwnd) { if (!IsInit) return false; if (m_bGrabbing) return true; this.previewHwnd= preview_Hwnd; // ch:标志位置位true | en:Set position bit true m_bGrabbing = true; m_hReceiveThread = new Thread(ReceiveThreadProcess); m_hReceiveThread.Start(); // ch:开始采集 | en:Start Grabbing int nRet = m_MyCamera.MV_CC_StartGrabbing_NET(); if (MyCamera.MV_OK != nRet) { m_bGrabbing = false; m_hReceiveThread.Join(); log?.Invoke(2, $"Start Grabbing Fail! ({nRet})"); return false; } return true; } public bool stop() { if (!IsInit) return false; if (!m_bGrabbing) return true; // ch:标志位设为false | en:Set flag bit false m_bGrabbing = false; m_hReceiveThread.Join(); // ch:停止采集 | en:Stop Grabbing int nRet = m_MyCamera.MV_CC_StopGrabbing_NET(); if (nRet != MyCamera.MV_OK) { log?.Invoke(2, $"Stop Grabbing Fail! ({nRet})"); return false; } return true; } #region private /// /// false-软触发 true-连续 /// /// public void setMode(bool isContinuous) { if (isContinuous) { m_MyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF); } else { m_MyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON); // ch:触发源选择:0 - Line0; // 1 - Line1; // 2 - Line2; // 3 - Line3; // 4 - Counter; // 7 - Software; //if (cbSoftTrigger.Checked) m_MyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); //else // m_MyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0); } isContinuousMode = isContinuous; } public void setPreviewWin(IntPtr preview_Hwnd) { this.previewHwnd = preview_Hwnd; } public void ReceiveThreadProcess() { MyCamera.MV_FRAME_OUT stFrameInfo = new MyCamera.MV_FRAME_OUT(); MyCamera.MV_DISPLAY_FRAME_INFO stDisplayInfo = new MyCamera.MV_DISPLAY_FRAME_INFO(); int nRet = MyCamera.MV_OK; while (m_bGrabbing) { nRet = m_MyCamera.MV_CC_GetImageBuffer_NET(ref stFrameInfo, 1000); if (nRet == MyCamera.MV_OK) { if (RemoveCustomPixelFormats(stFrameInfo.stFrameInfo.enPixelType) || stFrameInfo.stFrameInfo.nFrameLen == 0) { m_MyCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo); continue; } //pictureBox1显示 if (this.previewHwnd != IntPtr.Zero && IsWindow(this.previewHwnd)) { stDisplayInfo.hWnd = this.previewHwnd;// pictureBox1.Handle; stDisplayInfo.pData = stFrameInfo.pBufAddr; stDisplayInfo.nDataLen = stFrameInfo.stFrameInfo.nFrameLen; stDisplayInfo.nWidth = stFrameInfo.stFrameInfo.nWidth; stDisplayInfo.nHeight = stFrameInfo.stFrameInfo.nHeight; stDisplayInfo.enPixelType = stFrameInfo.stFrameInfo.enPixelType; m_MyCamera.MV_CC_DisplayOneFrame_NET(ref stDisplayInfo); } //保存 if (this.scanNum>0)//save tag { MyCamera.MV_SAVE_IMG_TO_FILE_PARAM stSaveFileParam = new MyCamera.MV_SAVE_IMG_TO_FILE_PARAM(); //lock (BufForDriverLock) { stSaveFileParam.enImageType = MyCamera.MV_SAVE_IAMGE_TYPE.MV_Image_Bmp; stSaveFileParam.enPixelType = stFrameInfo.stFrameInfo.enPixelType; stSaveFileParam.pData = stFrameInfo.pBufAddr;//m_BufForDriver; stSaveFileParam.nDataLen = stFrameInfo.stFrameInfo.nFrameLen; stSaveFileParam.nHeight = stFrameInfo.stFrameInfo.nHeight; stSaveFileParam.nWidth = stFrameInfo.stFrameInfo.nWidth; stSaveFileParam.iMethodValue = 2; //Save path stSaveFileParam.pImagePath = "Image_w" + stSaveFileParam.nWidth.ToString() + "_h" + stSaveFileParam.nHeight.ToString() + "_fn" + stFrameInfo.stFrameInfo.nFrameNum.ToString() + ".bmp"; nRet = m_MyCamera.MV_CC_SaveImageToFile_NET(ref stSaveFileParam); if (MyCamera.MV_OK == nRet) { ScanEvent?.Invoke(this.scanNum--, stSaveFileParam.pImagePath); } } } //free m_MyCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo); } else { Thread.Sleep(5); } } } // ch:去除自定义的像素格式 | en:Remove custom pixel formats private bool RemoveCustomPixelFormats(MyCamera.MvGvspPixelType enPixelFormat) { Int32 nResult = ((int)enPixelFormat) & (unchecked((Int32)0x80000000)); if (0x80000000 == nResult) { return true; } else { return false; } } #endregion public void getParam() { if (!IsInit) return; MyCamera.MVCC_FLOATVALUE stParam = new MyCamera.MVCC_FLOATVALUE(); int nRet = m_MyCamera.MV_CC_GetFloatValue_NET("ExposureTime", ref stParam); if (MyCamera.MV_OK == nRet) { ExposureTime = stParam.fCurValue;//.ToString("F1"); } nRet = m_MyCamera.MV_CC_GetFloatValue_NET("Gain", ref stParam); if (MyCamera.MV_OK == nRet) { Gain = stParam.fCurValue;//.ToString("F1"); } nRet = m_MyCamera.MV_CC_GetFloatValue_NET("ResultingFrameRate", ref stParam); if (MyCamera.MV_OK == nRet) { ResultingFrameRate = stParam.fCurValue;//.ToString("F1"); } } public void setParam(float exposureTime, float gain, float resultingFrameRate) { if (!IsInit) return; m_MyCamera.MV_CC_SetEnumValue_NET("ExposureAuto", 0); int nRet = m_MyCamera.MV_CC_SetFloatValue_NET("ExposureTime", exposureTime); if (nRet != MyCamera.MV_OK) { log?.Invoke(0, $"Set Exposure Time Fail! ({nRet})"); } m_MyCamera.MV_CC_SetEnumValue_NET("GainAuto", 0); nRet = m_MyCamera.MV_CC_SetFloatValue_NET("Gain", gain); if (nRet != MyCamera.MV_OK) { log?.Invoke(0, $"Set Gain Time Fail! ({nRet})"); } nRet = m_MyCamera.MV_CC_SetFloatValue_NET("AcquisitionFrameRate", resultingFrameRate); if (nRet != MyCamera.MV_OK) { log?.Invoke(0, $"Set AcquisitionFrameRate Time Fail! ({nRet})"); } } public bool scan(int num) { if (!IsInit) return false; if (!isContinuousMode) { // ch:触发命令 | en:Trigger command int nRet = m_MyCamera.MV_CC_SetCommandValue_NET("TriggerSoftware"); if (MyCamera.MV_OK != nRet) { log?.Invoke(0, $"Trigger Software Fail! ({nRet})"); return false; } } this.scanNum= num; return true; } public void Dispose() { stop(); } } }