版博士V2.0程序
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 

443 satır
17 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Reflection;
  7. using System.Runtime.InteropServices;
  8. using System.Text;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. using System.Timers;
  12. using System.Windows.Forms;
  13. using MvCamCtrl.NET;
  14. using Newtonsoft.Json.Linq;
  15. using static ControllerDllCSharp.ClassLibControllerDll;
  16. namespace ProductionControl.Device
  17. {
  18. public class Scanner : IDisposable
  19. {
  20. [DllImport("user32.dll")]
  21. [return: MarshalAs(UnmanagedType.Bool)]
  22. private static extern bool IsWindow(IntPtr hWnd);
  23. public enum ScannerType
  24. {
  25. [Description("板卡相机")]
  26. GENTL = 0,
  27. [Description("网口相机")]
  28. CC = 1,
  29. }
  30. private ScannerType scannerType;
  31. public Action<int, string> log;
  32. /// <summary>
  33. /// 拍照回传 (1-num,文件名.bmp)
  34. /// </summary>
  35. public Action<int, string> ScanEvent;
  36. /// <summary>
  37. /// 曝光
  38. /// </summary>
  39. public float ExposureTime { get; private set; }
  40. /// <summary>
  41. /// 增益
  42. /// </summary>
  43. public float Gain { get; private set; }
  44. /// <summary>
  45. /// 帧率
  46. /// </summary>
  47. public float ResultingFrameRate { get; private set; }
  48. /// <summary>
  49. /// 是否连续模式
  50. /// </summary>
  51. public bool isContinuousMode { get; private set; }
  52. /// <summary>
  53. /// 是否打开设备成功
  54. /// </summary>
  55. public bool IsInit { get; private set; } = false;
  56. //public string ErrInfo { get; private set; }
  57. //private System.Timers.Timer timer = new System.Timers.Timer();
  58. #region
  59. private MyCamera.MV_GENTL_DEV_INFO_LIST m_stGentDeviceList = new MyCamera.MV_GENTL_DEV_INFO_LIST();
  60. private MyCamera.MV_GENTL_IF_INFO_LIST m_stIFInfoList = new MyCamera.MV_GENTL_IF_INFO_LIST();
  61. private MyCamera.MV_CC_DEVICE_INFO_LIST m_stCCDeviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
  62. private MyCamera m_MyCamera = new MyCamera();
  63. private bool m_bGrabbing = false;//开始采集TAG
  64. private Thread m_hReceiveThread = null;
  65. //显示图像控件句柄
  66. private IntPtr previewHwnd = IntPtr.Zero;
  67. //拍照数量
  68. private int scanNum = 0;
  69. #endregion
  70. public Scanner(ScannerType type)
  71. {
  72. this.scannerType = type;
  73. }
  74. public bool open()
  75. {
  76. if (IsInit) return true;
  77. System.GC.Collect();
  78. int nRet;
  79. if (this.scannerType==ScannerType.GENTL)
  80. {
  81. nRet = MyCamera.MV_CC_EnumInterfacesByGenTL_NET(ref m_stIFInfoList, Config.Scanner_GENTL_CTI);
  82. if (0 != nRet || m_stIFInfoList.nInterfaceNum<1)
  83. {
  84. log?.Invoke(2, $"Enumerate interfaces fail! ({nRet})");
  85. return false;
  86. }
  87. //
  88. MyCamera.MV_GENTL_IF_INFO stIFInfo = (MyCamera.MV_GENTL_IF_INFO)Marshal.PtrToStructure(m_stIFInfoList.pIFInfo[0], typeof(MyCamera.MV_GENTL_IF_INFO));
  89. nRet = MyCamera.MV_CC_EnumDevicesByGenTL_NET(ref stIFInfo, ref m_stGentDeviceList);
  90. if (0 != nRet || m_stGentDeviceList.nDeviceNum<1)
  91. {
  92. log?.Invoke(2, $"Enumerate devices fail! ({nRet})");
  93. return false;
  94. }
  95. // ch:获取选择的设备信息 | en:Get selected device information
  96. MyCamera.MV_GENTL_DEV_INFO device = (MyCamera.MV_GENTL_DEV_INFO)Marshal.PtrToStructure(m_stGentDeviceList.pDeviceInfo[0], typeof(MyCamera.MV_GENTL_DEV_INFO));
  97. // ch:打开设备 | en:Open device
  98. if (null == m_MyCamera)
  99. {
  100. m_MyCamera = new MyCamera();
  101. if (null == m_MyCamera)
  102. {
  103. log?.Invoke(2, $"Open device fail!");
  104. return false;
  105. }
  106. }
  107. nRet = m_MyCamera.MV_CC_CreateDeviceByGenTL_NET(ref device);
  108. if (MyCamera.MV_OK != nRet)
  109. {
  110. log?.Invoke(2, $"Open device fail! ({nRet})");
  111. return false;
  112. }
  113. nRet = m_MyCamera.MV_CC_OpenDevice_NET();
  114. if (MyCamera.MV_OK != nRet)
  115. {
  116. m_MyCamera.MV_CC_DestroyDevice_NET();
  117. log?.Invoke(2, $"Device open fail! ({nRet})");
  118. return false;
  119. }
  120. }
  121. else //CC
  122. {
  123. nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_stCCDeviceList);
  124. if (0 != nRet || m_stCCDeviceList.nDeviceNum<1)
  125. {
  126. log?.Invoke(2, $"Enumerate devices fail! ({nRet})");
  127. return false;
  128. }
  129. // ch:获取选择的设备信息
  130. MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_stCCDeviceList.pDeviceInfo[0], typeof(MyCamera.MV_CC_DEVICE_INFO));
  131. // ch:打开设备 | en:Open device
  132. if (null == m_MyCamera)
  133. {
  134. m_MyCamera = new MyCamera();
  135. if (null == m_MyCamera)
  136. {
  137. log?.Invoke(2, $"Open device fail!");
  138. return false;
  139. }
  140. }
  141. nRet = m_MyCamera.MV_CC_CreateDevice_NET(ref device);
  142. if (MyCamera.MV_OK != nRet)
  143. {
  144. log?.Invoke(2, $"Open device fail! ({nRet})");
  145. return false;
  146. }
  147. nRet = m_MyCamera.MV_CC_OpenDevice_NET();
  148. if (MyCamera.MV_OK != nRet)
  149. {
  150. m_MyCamera.MV_CC_DestroyDevice_NET();
  151. log?.Invoke(2, $"Open device fail! ({nRet})");
  152. return false;
  153. }
  154. // ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
  155. if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
  156. {
  157. int nPacketSize = m_MyCamera.MV_CC_GetOptimalPacketSize_NET();
  158. if (nPacketSize > 0)
  159. {
  160. nRet = m_MyCamera.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize);
  161. //if (nRet != MyCamera.MV_OK)
  162. //{
  163. // ShowErrorMsg("Set Packet Size failed!", nRet);
  164. //}
  165. }
  166. else
  167. {
  168. //ShowErrorMsg("Get Packet Size failed!", nPacketSize);
  169. }
  170. }
  171. }
  172. // ch:设置采集[软触发/连续]模式 | en:Set Continues Aquisition Mode
  173. m_MyCamera.MV_CC_SetEnumValue_NET("AcquisitionMode", (uint)MyCamera.MV_CAM_ACQUISITION_MODE.MV_ACQ_MODE_CONTINUOUS);
  174. setMode(false); //软触发
  175. //
  176. getParam();
  177. IsInit = true;
  178. //timer.Elapsed += Timer_Elapsed;
  179. //timer.Interval = 100;
  180. //timer.Enabled = true;
  181. return true;
  182. }
  183. public void close()
  184. {
  185. if (!IsInit) return;
  186. IsInit = false;
  187. // ch:取流标志位清零 | en:Reset flow flag bit
  188. if (m_bGrabbing == true)
  189. {
  190. m_bGrabbing = false;
  191. m_hReceiveThread.Join();
  192. }
  193. // ch:关闭设备 | en:Close Device
  194. m_MyCamera.MV_CC_CloseDevice_NET();
  195. m_MyCamera.MV_CC_DestroyDevice_NET();
  196. }
  197. /// <summary>
  198. ///
  199. /// </summary>
  200. /// <param name="hwnd">显示图像控件句柄</param>
  201. /// <returns></returns>
  202. public bool start(IntPtr preview_Hwnd)
  203. {
  204. if (!IsInit) return false;
  205. if (m_bGrabbing) return true;
  206. this.previewHwnd= preview_Hwnd;
  207. // ch:标志位置位true | en:Set position bit true
  208. m_bGrabbing = true;
  209. m_hReceiveThread = new Thread(ReceiveThreadProcess);
  210. m_hReceiveThread.Start();
  211. // ch:开始采集 | en:Start Grabbing
  212. int nRet = m_MyCamera.MV_CC_StartGrabbing_NET();
  213. if (MyCamera.MV_OK != nRet)
  214. {
  215. m_bGrabbing = false;
  216. m_hReceiveThread.Join();
  217. log?.Invoke(2, $"Start Grabbing Fail! ({nRet})");
  218. return false;
  219. }
  220. return true;
  221. }
  222. public bool stop()
  223. {
  224. if (!IsInit) return false;
  225. if (!m_bGrabbing) return true;
  226. // ch:标志位设为false | en:Set flag bit false
  227. m_bGrabbing = false;
  228. m_hReceiveThread.Join();
  229. // ch:停止采集 | en:Stop Grabbing
  230. int nRet = m_MyCamera.MV_CC_StopGrabbing_NET();
  231. if (nRet != MyCamera.MV_OK)
  232. {
  233. log?.Invoke(2, $"Stop Grabbing Fail! ({nRet})");
  234. return false;
  235. }
  236. return true;
  237. }
  238. #region private
  239. /// <summary>
  240. /// false-软触发 true-连续
  241. /// </summary>
  242. /// <param name="type"></param>
  243. public void setMode(bool isContinuous)
  244. {
  245. if (isContinuous)
  246. {
  247. m_MyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF);
  248. }
  249. else
  250. {
  251. m_MyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
  252. // ch:触发源选择:0 - Line0;
  253. // 1 - Line1;
  254. // 2 - Line2;
  255. // 3 - Line3;
  256. // 4 - Counter;
  257. // 7 - Software;
  258. //if (cbSoftTrigger.Checked)
  259. m_MyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
  260. //else
  261. // m_MyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0);
  262. }
  263. isContinuousMode = isContinuous;
  264. }
  265. public void setPreviewWin(IntPtr preview_Hwnd)
  266. {
  267. this.previewHwnd = preview_Hwnd;
  268. }
  269. public void ReceiveThreadProcess()
  270. {
  271. MyCamera.MV_FRAME_OUT stFrameInfo = new MyCamera.MV_FRAME_OUT();
  272. MyCamera.MV_DISPLAY_FRAME_INFO stDisplayInfo = new MyCamera.MV_DISPLAY_FRAME_INFO();
  273. int nRet = MyCamera.MV_OK;
  274. while (m_bGrabbing)
  275. {
  276. nRet = m_MyCamera.MV_CC_GetImageBuffer_NET(ref stFrameInfo, 1000);
  277. if (nRet == MyCamera.MV_OK)
  278. {
  279. if (RemoveCustomPixelFormats(stFrameInfo.stFrameInfo.enPixelType)
  280. || stFrameInfo.stFrameInfo.nFrameLen == 0)
  281. {
  282. m_MyCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo);
  283. continue;
  284. }
  285. //pictureBox1显示
  286. if (this.previewHwnd != IntPtr.Zero && IsWindow(this.previewHwnd))
  287. {
  288. stDisplayInfo.hWnd = this.previewHwnd;// pictureBox1.Handle;
  289. stDisplayInfo.pData = stFrameInfo.pBufAddr;
  290. stDisplayInfo.nDataLen = stFrameInfo.stFrameInfo.nFrameLen;
  291. stDisplayInfo.nWidth = stFrameInfo.stFrameInfo.nWidth;
  292. stDisplayInfo.nHeight = stFrameInfo.stFrameInfo.nHeight;
  293. stDisplayInfo.enPixelType = stFrameInfo.stFrameInfo.enPixelType;
  294. m_MyCamera.MV_CC_DisplayOneFrame_NET(ref stDisplayInfo);
  295. }
  296. //保存
  297. if (this.scanNum>0)//save tag
  298. {
  299. MyCamera.MV_SAVE_IMG_TO_FILE_PARAM stSaveFileParam = new MyCamera.MV_SAVE_IMG_TO_FILE_PARAM();
  300. //lock (BufForDriverLock)
  301. {
  302. stSaveFileParam.enImageType = MyCamera.MV_SAVE_IAMGE_TYPE.MV_Image_Bmp;
  303. stSaveFileParam.enPixelType = stFrameInfo.stFrameInfo.enPixelType;
  304. stSaveFileParam.pData = stFrameInfo.pBufAddr;//m_BufForDriver;
  305. stSaveFileParam.nDataLen = stFrameInfo.stFrameInfo.nFrameLen;
  306. stSaveFileParam.nHeight = stFrameInfo.stFrameInfo.nHeight;
  307. stSaveFileParam.nWidth = stFrameInfo.stFrameInfo.nWidth;
  308. stSaveFileParam.iMethodValue = 2;
  309. //Save path
  310. stSaveFileParam.pImagePath = "Image_w" + stSaveFileParam.nWidth.ToString() + "_h" + stSaveFileParam.nHeight.ToString() + "_fn" + stFrameInfo.stFrameInfo.nFrameNum.ToString() + ".bmp";
  311. nRet = m_MyCamera.MV_CC_SaveImageToFile_NET(ref stSaveFileParam);
  312. if (MyCamera.MV_OK == nRet)
  313. {
  314. ScanEvent?.Invoke(this.scanNum--, stSaveFileParam.pImagePath);
  315. }
  316. }
  317. }
  318. //free
  319. m_MyCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo);
  320. }
  321. else
  322. {
  323. Thread.Sleep(5);
  324. }
  325. }
  326. }
  327. // ch:去除自定义的像素格式 | en:Remove custom pixel formats
  328. private bool RemoveCustomPixelFormats(MyCamera.MvGvspPixelType enPixelFormat)
  329. {
  330. Int32 nResult = ((int)enPixelFormat) & (unchecked((Int32)0x80000000));
  331. if (0x80000000 == nResult)
  332. {
  333. return true;
  334. }
  335. else
  336. {
  337. return false;
  338. }
  339. }
  340. #endregion
  341. public void getParam()
  342. {
  343. if (!IsInit) return;
  344. MyCamera.MVCC_FLOATVALUE stParam = new MyCamera.MVCC_FLOATVALUE();
  345. int nRet = m_MyCamera.MV_CC_GetFloatValue_NET("ExposureTime", ref stParam);
  346. if (MyCamera.MV_OK == nRet)
  347. {
  348. ExposureTime = stParam.fCurValue;//.ToString("F1");
  349. }
  350. nRet = m_MyCamera.MV_CC_GetFloatValue_NET("Gain", ref stParam);
  351. if (MyCamera.MV_OK == nRet)
  352. {
  353. Gain = stParam.fCurValue;//.ToString("F1");
  354. }
  355. nRet = m_MyCamera.MV_CC_GetFloatValue_NET("ResultingFrameRate", ref stParam);
  356. if (MyCamera.MV_OK == nRet)
  357. {
  358. ResultingFrameRate = stParam.fCurValue;//.ToString("F1");
  359. }
  360. }
  361. public void setParam(float exposureTime, float gain, float resultingFrameRate)
  362. {
  363. if (!IsInit) return;
  364. m_MyCamera.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
  365. int nRet = m_MyCamera.MV_CC_SetFloatValue_NET("ExposureTime", exposureTime);
  366. if (nRet != MyCamera.MV_OK)
  367. {
  368. log?.Invoke(0, $"Set Exposure Time Fail! ({nRet})");
  369. }
  370. m_MyCamera.MV_CC_SetEnumValue_NET("GainAuto", 0);
  371. nRet = m_MyCamera.MV_CC_SetFloatValue_NET("Gain", gain);
  372. if (nRet != MyCamera.MV_OK)
  373. {
  374. log?.Invoke(0, $"Set Gain Time Fail! ({nRet})");
  375. }
  376. nRet = m_MyCamera.MV_CC_SetFloatValue_NET("AcquisitionFrameRate", resultingFrameRate);
  377. if (nRet != MyCamera.MV_OK)
  378. {
  379. log?.Invoke(0, $"Set AcquisitionFrameRate Time Fail! ({nRet})");
  380. }
  381. }
  382. public bool scan(int num)
  383. {
  384. if (!IsInit) return false;
  385. if (!isContinuousMode)
  386. {
  387. // ch:触发命令 | en:Trigger command
  388. int nRet = m_MyCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");
  389. if (MyCamera.MV_OK != nRet)
  390. {
  391. log?.Invoke(0, $"Trigger Software Fail! ({nRet})");
  392. return false;
  393. }
  394. }
  395. this.scanNum= num;
  396. return true;
  397. }
  398. public void Dispose()
  399. {
  400. stop();
  401. }
  402. }
  403. }