GalaxyCamera.cs 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213
  1. using Cognex.VisionPro;
  2. using GxIAPINET;
  3. using MathNet.Numerics.LinearAlgebra;
  4. using Microsoft.Win32;
  5. using NPOI.Util;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.ComponentModel;
  9. using System.Diagnostics;
  10. using System.Drawing;
  11. using System.Drawing.Imaging;
  12. using System.Runtime.CompilerServices;
  13. using System.Runtime.InteropServices;
  14. using System.Text.RegularExpressions;
  15. using System.Threading;
  16. using System.Threading.Tasks;
  17. using TeamAAS_VP.Core.GalaxyMethod;
  18. using TeamAAS_VP.Enums;
  19. using TeamAAS_VP.Interfaces;
  20. using TeamAAS_VP.Models;
  21. namespace TeamAAS_VP.Core.Cameras
  22. {
  23. public class GalaxyCamera : CameraBase, ICamera, INotifyPropertyChanged
  24. {
  25. #region 字段
  26. private Thread m_hReceiveThread;
  27. static IGXFactory m_objIGXFactory = null; //Factory对像
  28. IGXDevice m_objIGXDevice = null; //设备对像
  29. IGXStream m_objIGXStream = null; //流对像
  30. static List<IGXDeviceInfo> m_listIGXDeviceInfo = new List<IGXDeviceInfo>(); //设备信息列表
  31. IGXFeatureControl m_objIGXFeatureControl = null; //远端设备属性控制器对像
  32. IGXFeatureControl m_objIGXStreamFeatureControl = null; //流层属性控制器对象
  33. IntPtr m_pOutBuffer = IntPtr.Zero; //图像质量提升或图像格式转换输出Buffer
  34. IntPtr m_pBitmapInfo = IntPtr.Zero;
  35. bool m_bIsColor = false; ///<是否支持彩色相机
  36. byte[] m_byMonoBuffer = null; ///<黑白相机buffer
  37. byte[] m_byColorBuffer = null; ///<彩色相机buffer
  38. int m_nWidth = 0; ///<图像宽度
  39. int m_nHeight = 0; ///<图像高度
  40. IGXImageFormatConvert m_objImageFormatConvert = null; ///<IGXImageFormatConvert对象,仅供图像格式转换使用
  41. CWin32Bitmaps.BITMAPINFO m_objBitmapInfo = new CWin32Bitmaps.BITMAPINFO();
  42. #endregion
  43. #region 属性
  44. /// <summary>
  45. /// 是否是3D相机
  46. /// </summary>
  47. public bool Is3D { get; } = false;
  48. public string Name { get; private set; }
  49. public Guid ID { get; private set; }
  50. public int Index { get; set; }
  51. public CameraBrand CameraBrand { get => CameraBrand.Galaxy; }
  52. public bool IsFindByIp { get; private set; }
  53. public string ManufacturerName { get; private set; }
  54. public string ModelName { get; private set; }
  55. public string SerialNumber { get; private set; }
  56. public string CameraIp { get; private set; }
  57. public CameraType CameraType { get; private set; }
  58. private bool _IsGrabbing;
  59. /// <summary>
  60. /// 正在采集
  61. /// </summary>
  62. public bool IsGrabbing
  63. {
  64. get { return _IsGrabbing; }
  65. private set { SetProperty(ref _IsGrabbing, value); }
  66. }
  67. private ICogImage _Image;
  68. public ICogImage Image
  69. {
  70. get { return _Image; }
  71. private set { SetProperty(ref _Image, value); }
  72. }
  73. public bool IsConnected { get; private set; }
  74. public TimeSpan TotalTime { get; private set; }
  75. public string ErrorMessage { get; private set; }
  76. public uint ImageWidth { get; private set; }
  77. public uint ImageHeight { get; private set; }
  78. private bool IsHaveCamera = false;
  79. #endregion
  80. #region 事件
  81. public event Action<ICogImage, TimeSpan, string,Guid> ImageCallbackEvent;
  82. public event Action<Guid, bool> CameraConnectChangedEvent;
  83. #endregion
  84. public GalaxyCamera(Guid id, int index, string name, string serialNumber, string cameraip, bool isFindByIp)
  85. {
  86. ID = id;
  87. Name = serialNumber;
  88. Index = index;
  89. CameraIp = cameraip;
  90. SerialNumber = serialNumber;
  91. IsFindByIp = isFindByIp;
  92. var list = GetDevices();
  93. foreach (var device in list)
  94. {
  95. if (device.CameraType== CameraType.GIGE)
  96. {
  97. if (IsFindByIp)
  98. {
  99. if (device.CameraIp == CameraIp)
  100. {
  101. IsHaveCamera = true;
  102. ManufacturerName = device.ManufacturerName;
  103. ModelName = device.Model;
  104. SerialNumber = device.SerialNumber;
  105. CameraType = CameraType.GIGE;
  106. break;
  107. }
  108. }
  109. else
  110. {
  111. if (device.SerialNumber == serialNumber)
  112. {
  113. IsHaveCamera = true;
  114. ManufacturerName = device.ManufacturerName;
  115. ModelName = device.Model;
  116. SerialNumber = device.SerialNumber;
  117. CameraType = CameraType.GIGE;
  118. break;
  119. }
  120. }
  121. }
  122. else
  123. {
  124. if (device.SerialNumber == serialNumber)
  125. {
  126. IsHaveCamera = true;
  127. ManufacturerName = device.ManufacturerName;
  128. ModelName = device.Model;
  129. SerialNumber = device.SerialNumber;
  130. CameraType = CameraType.GIGE;
  131. break;
  132. }
  133. }
  134. }
  135. IsConnected = false;
  136. }
  137. #region 方法
  138. /// <summary>
  139. /// 获取设备
  140. /// </summary>
  141. /// <returns></returns>
  142. public static CameraInfo[] GetDevices()
  143. {
  144. m_objIGXFactory = IGXFactory.GetInstance();
  145. m_objIGXFactory.Init();//相机初始化
  146. List<CameraInfo> cameras = new List<CameraInfo>();
  147. if (!CheckSoftwareInstalled().isInstalled)
  148. {
  149. LogHelper.WriteLogInfo("未安装Galaxy Viewer");
  150. return cameras.ToArray();
  151. }
  152. m_listIGXDeviceInfo.Clear();
  153. if (null != m_objIGXFactory)
  154. {
  155. m_objIGXFactory.UpdateAllDeviceList(200, m_listIGXDeviceInfo);
  156. }
  157. // 判断当前连接设备个数
  158. if (m_listIGXDeviceInfo.Count <= 0)
  159. {
  160. LogHelper.WriteLogInfo("未检测到设备,请确保设备正常连接然后重启程序!");
  161. return cameras.ToArray();
  162. }
  163. for (int i = 0; i < m_listIGXDeviceInfo.Count; i++)
  164. {
  165. var deviceType = m_listIGXDeviceInfo[i].GetDeviceClass();
  166. if (deviceType == GX_DEVICE_CLASS_LIST.GX_DEVICE_CLASS_GEV)
  167. {
  168. cameras.Add(new Models.CameraInfo()
  169. {
  170. CameraNo = i + 1,
  171. CameraName = m_listIGXDeviceInfo[i].GetDisplayName(),
  172. CameraBrand = CameraBrand.Galaxy,
  173. CameraType = CameraType.GIGE,
  174. ManufacturerName = m_listIGXDeviceInfo[i].GetVendorName(),
  175. Model = m_listIGXDeviceInfo[i].GetModelName(),
  176. SerialNumber = m_listIGXDeviceInfo[i].GetSN(),
  177. CameraIp = m_listIGXDeviceInfo[i].GetIP(),
  178. IsFindByIp=true,
  179. });
  180. }
  181. else if (deviceType == GX_DEVICE_CLASS_LIST.GX_DEVICE_CLASS_USB2 || deviceType == GX_DEVICE_CLASS_LIST.GX_DEVICE_CLASS_U3V)
  182. {
  183. cameras.Add(new Models.CameraInfo()
  184. {
  185. CameraNo = i + 1,
  186. CameraName = m_listIGXDeviceInfo[i].GetDisplayName(),
  187. CameraBrand = CameraBrand.Galaxy,
  188. CameraType = CameraType.USB,
  189. ManufacturerName = m_listIGXDeviceInfo[i].GetVendorName(),
  190. Model = m_listIGXDeviceInfo[i].GetModelName(),
  191. SerialNumber = m_listIGXDeviceInfo[i].GetSN(),
  192. CameraIp = "",
  193. });
  194. }
  195. else if (deviceType == GX_DEVICE_CLASS_LIST.GX_DEVICE_CLASS_UNKNOWN)
  196. {
  197. cameras.Add(new Models.CameraInfo()
  198. {
  199. CameraNo = i + 1,
  200. CameraName = m_listIGXDeviceInfo[i].GetDisplayName(),
  201. CameraBrand = CameraBrand.Galaxy,
  202. CameraType = CameraType.Unknown,
  203. ManufacturerName = m_listIGXDeviceInfo[i].GetVendorName(),
  204. Model = m_listIGXDeviceInfo[i].GetModelName(),
  205. SerialNumber = m_listIGXDeviceInfo[i].GetSN(),
  206. CameraIp = "",
  207. });
  208. }
  209. }
  210. return cameras.ToArray();
  211. }
  212. /// <summary>
  213. /// 检查相机软件是否安装
  214. /// </summary>
  215. /// <returns></returns>
  216. public static (bool isInstalled, string version) CheckSoftwareInstalled()
  217. {
  218. string softwareName = "Galaxy";
  219. string softwareVersion = "2.4.2504";
  220. string[] registryPaths = new[]
  221. {
  222. @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
  223. @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
  224. };
  225. foreach (var path in registryPaths)
  226. {
  227. using (RegistryKey key = Registry.LocalMachine.OpenSubKey(path))
  228. {
  229. if (key == null) continue;
  230. foreach (string subKeyName in key.GetSubKeyNames())
  231. {
  232. using (RegistryKey subKey = key.OpenSubKey(subKeyName))
  233. {
  234. string displayName = subKey.GetValue("DisplayName")?.ToString();
  235. if (displayName != null && displayName.Contains(softwareName))
  236. {
  237. string version = subKey.GetValue("DisplayName")?.ToString();
  238. var match = Regex.Match(version, @"\d+(?:\.\d+)+");
  239. if (match.Success)
  240. {
  241. version = match.Value;
  242. }
  243. else
  244. {
  245. continue;
  246. }
  247. Version v1 = new Version(version);
  248. Version v2 = new Version(softwareVersion);
  249. if (v1 >= v2)
  250. {
  251. return (true, version);
  252. }
  253. else
  254. {
  255. return (false, version);
  256. }
  257. }
  258. }
  259. }
  260. }
  261. }
  262. return (false, "");
  263. }
  264. public void CloseDevice()
  265. {
  266. EnterOperation();
  267. try
  268. {
  269. try
  270. {
  271. if (null != m_objIGXFeatureControl)
  272. {
  273. m_objIGXFeatureControl.GetCommandFeature("AcquisitionStop").Execute();
  274. m_objIGXFeatureControl = null;
  275. }
  276. //停止流通道、注销采集回调和关闭流
  277. if (null != m_objIGXStream)
  278. {
  279. m_objIGXStream.StopGrab();
  280. //注销采集回调函数
  281. m_objIGXStream.UnregisterCaptureCallback();
  282. m_objIGXStream.Close();
  283. m_objIGXStream = null;
  284. m_objIGXStreamFeatureControl = null;
  285. }
  286. //关闭设备
  287. if (null != m_objIGXDevice)
  288. {
  289. m_objIGXDevice.Close();
  290. m_objIGXDevice = null;
  291. }
  292. //反初始化
  293. if (null != m_objIGXFactory)
  294. {
  295. m_objIGXFactory.Uninit();
  296. }
  297. }
  298. catch (Exception)
  299. {
  300. }
  301. ReleaseBuffer();
  302. }
  303. finally
  304. {
  305. ExitOperation();
  306. }
  307. }
  308. public float GetExposureTime()
  309. {
  310. EnterOperation();
  311. try
  312. {
  313. if (null != m_objIGXFeatureControl)
  314. {
  315. double dCurShuter = m_objIGXFeatureControl.GetFloatFeature("ExposureTime").GetValue();
  316. return (float)dCurShuter;
  317. }
  318. else
  319. { return 0; }
  320. }
  321. finally
  322. {
  323. ExitOperation();
  324. }
  325. }
  326. public float GetGain()
  327. {
  328. EnterOperation();
  329. try
  330. {
  331. if (null != m_objIGXFeatureControl)
  332. {
  333. double dCurGain = m_objIGXFeatureControl.GetFloatFeature("Gain").GetValue();
  334. return (float)dCurGain;
  335. }
  336. else
  337. { return 0; }
  338. }
  339. finally
  340. {
  341. ExitOperation();
  342. }
  343. }
  344. public ICogImage Grab(bool isRealtime = true)
  345. {
  346. EnterOperation();
  347. try
  348. {
  349. IImageData objIImageData = null;
  350. Stopwatch sw = Stopwatch.StartNew();
  351. for (int j = 0; j < 5; j++)
  352. {
  353. try
  354. {
  355. if (null == m_objIGXDevice)
  356. {
  357. OpenDevice();
  358. }
  359. //开启采集流通道
  360. if (null != m_objIGXStream)
  361. {
  362. m_objIGXStream.StartGrab();
  363. }
  364. //发送开采命令
  365. if (null != m_objIGXFeatureControl)
  366. {
  367. m_objIGXFeatureControl.GetCommandFeature("AcquisitionStart").Execute();
  368. }
  369. objIImageData = m_objIGXStream.GetImageNoThrow(500);
  370. //===================================
  371. GX_VALID_BIT_LIST emValidBits = GX_VALID_BIT_LIST.GX_BIT_0_7;
  372. if (null != objIImageData)
  373. {
  374. emValidBits = GetBestValudBit(objIImageData.GetPixelFormat());
  375. if (GX_FRAME_STATUS_LIST.GX_FRAME_STATUS_SUCCESS == objIImageData.GetStatus())
  376. {
  377. if (m_bIsColor)
  378. {
  379. IntPtr pRGB24Buffer = IntPtr.Zero;
  380. if (objIImageData.GetPixelFormat() == GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BGR8)
  381. {
  382. byte[] byColorBufferTmp = new byte[__GetStride(m_nWidth, m_bIsColor) * m_nHeight];
  383. Marshal.Copy(objIImageData.GetBuffer(), byColorBufferTmp, 0, __GetStride(m_nWidth, m_bIsColor) * m_nHeight);
  384. pRGB24Buffer = objIImageData.GetBuffer();
  385. //BGR8格式需要翻转数据后显示
  386. for (int i = 0; i < m_nHeight; i++)
  387. {
  388. Buffer.BlockCopy(byColorBufferTmp, (m_nHeight - i - 1) * m_nWidth * 3, m_byColorBuffer, i * m_nWidth * 3, m_nWidth * 3);
  389. }
  390. }
  391. else
  392. {
  393. // 设置目标像素格式
  394. m_objImageFormatConvert.SetDstFormat(GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BGR8);
  395. // 获取目标像素格式Buffer大小
  396. UInt64 i64DstBufferize = m_objImageFormatConvert.GetBufferSizeForConversion(objIImageData);
  397. // 设置目标有效位数
  398. m_objImageFormatConvert.SetValidBits(emValidBits);
  399. // 进行图像格式转换
  400. m_objImageFormatConvert.Convert(objIImageData, m_pOutBuffer, i64DstBufferize, true);
  401. Marshal.Copy(m_pOutBuffer, m_byColorBuffer, 0, __GetStride(m_nWidth, m_bIsColor) * m_nHeight);
  402. pRGB24Buffer = m_pOutBuffer;
  403. }
  404. Image = ConvertImage((uint)m_nWidth, (uint)m_nHeight, pRGB24Buffer, GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BGR8);
  405. }
  406. else
  407. {
  408. IntPtr pRaw8Buffer = IntPtr.Zero;
  409. if (__IsPixelFormat8(objIImageData.GetPixelFormat()))
  410. {
  411. byte[] byMonoBufferTmp = new byte[__GetStride(m_nWidth, m_bIsColor) * m_nHeight];
  412. Marshal.Copy(objIImageData.GetBuffer(), byMonoBufferTmp, 0, __GetStride(m_nWidth, m_bIsColor) * m_nHeight);
  413. pRaw8Buffer = objIImageData.GetBuffer();
  414. // 黑白相机需要翻转数据后显示
  415. for (int i = 0; i < m_nHeight; i++)
  416. {
  417. Buffer.BlockCopy(byMonoBufferTmp, (m_nHeight - i - 1) * m_nWidth, m_byMonoBuffer, i * m_nWidth, m_nWidth);
  418. }
  419. }
  420. else
  421. {
  422. // 设置目标像素格式
  423. m_objImageFormatConvert.SetDstFormat(GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO8);
  424. // 获取目标像素格式Buffer大小
  425. UInt64 i64DstBufferize = m_objImageFormatConvert.GetBufferSizeForConversion(objIImageData);
  426. // 设置目标有效位数
  427. m_objImageFormatConvert.SetValidBits(emValidBits);
  428. // 进行图像格式转换
  429. m_objImageFormatConvert.Convert(objIImageData, m_pOutBuffer, i64DstBufferize, true);
  430. Marshal.Copy(m_pOutBuffer, m_byMonoBuffer, 0, __GetStride(m_nWidth, m_bIsColor) * m_nHeight);
  431. pRaw8Buffer = m_pOutBuffer;
  432. }
  433. Image = ConvertImage((uint)m_nWidth, (uint)m_nHeight, pRaw8Buffer, GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO8);
  434. }
  435. }
  436. }
  437. if (Image != null)
  438. {
  439. ErrorMessage = "";
  440. TotalTime = sw.Elapsed;
  441. return Image;
  442. }
  443. }
  444. catch (Exception ex)
  445. {
  446. CloseDevice();
  447. OpenDevice();
  448. ErrorMessage = ex.Message;
  449. }
  450. finally
  451. {
  452. if (null != objIImageData)
  453. {
  454. //用完之后释放资源
  455. objIImageData.Destroy();
  456. }
  457. }
  458. }
  459. if (IsConnected)
  460. {
  461. IsConnected = false;
  462. CameraConnectChangedEvent?.Invoke(ID, false);
  463. }
  464. return null;
  465. }
  466. finally
  467. {
  468. ExitOperation();
  469. }
  470. }
  471. public ICogImage Grab2(bool isRealtime = true)
  472. {
  473. EnterOperation();
  474. try
  475. {
  476. IImageData objIImageData = null;
  477. Stopwatch sw = Stopwatch.StartNew();
  478. for (int j = 0; j < 5; j++)
  479. {
  480. try
  481. {
  482. if (null == m_objIGXDevice)
  483. {
  484. OpenDevice();
  485. }
  486. //开启采集流通道
  487. if (null != m_objIGXStream)
  488. {
  489. m_objIGXStream.StartGrab();
  490. }
  491. //发送开采命令
  492. if (null != m_objIGXFeatureControl)
  493. {
  494. m_objIGXFeatureControl.GetCommandFeature("AcquisitionStart").Execute();
  495. }
  496. objIImageData = m_objIGXStream.GetImageNoThrow(500);
  497. //===================================
  498. GX_VALID_BIT_LIST emValidBits = GX_VALID_BIT_LIST.GX_BIT_0_7;
  499. if (null != objIImageData)
  500. {
  501. emValidBits = GetBestValudBit(objIImageData.GetPixelFormat());
  502. if (GX_FRAME_STATUS_LIST.GX_FRAME_STATUS_SUCCESS == objIImageData.GetStatus())
  503. {
  504. if (m_bIsColor)
  505. {
  506. IntPtr pRGB24Buffer = IntPtr.Zero;
  507. if (objIImageData.GetPixelFormat() == GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BGR8)
  508. {
  509. byte[] byColorBufferTmp = new byte[__GetStride(m_nWidth, m_bIsColor) * m_nHeight];
  510. Marshal.Copy(objIImageData.GetBuffer(), byColorBufferTmp, 0, __GetStride(m_nWidth, m_bIsColor) * m_nHeight);
  511. pRGB24Buffer = objIImageData.GetBuffer();
  512. //BGR8格式需要翻转数据后显示
  513. for (int i = 0; i < m_nHeight; i++)
  514. {
  515. Buffer.BlockCopy(byColorBufferTmp, (m_nHeight - i - 1) * m_nWidth * 3, m_byColorBuffer, i * m_nWidth * 3, m_nWidth * 3);
  516. }
  517. }
  518. else
  519. {
  520. // 设置目标像素格式
  521. m_objImageFormatConvert.SetDstFormat(GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BGR8);
  522. // 获取目标像素格式Buffer大小
  523. UInt64 i64DstBufferize = m_objImageFormatConvert.GetBufferSizeForConversion(objIImageData);
  524. // 设置目标有效位数
  525. m_objImageFormatConvert.SetValidBits(emValidBits);
  526. // 进行图像格式转换
  527. m_objImageFormatConvert.Convert(objIImageData, m_pOutBuffer, i64DstBufferize, true);
  528. Marshal.Copy(m_pOutBuffer, m_byColorBuffer, 0, __GetStride(m_nWidth, m_bIsColor) * m_nHeight);
  529. pRGB24Buffer = m_pOutBuffer;
  530. }
  531. Image = ConvertImage((uint)m_nWidth, (uint)m_nHeight, pRGB24Buffer, GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BGR8);
  532. }
  533. else
  534. {
  535. IntPtr pRaw8Buffer = IntPtr.Zero;
  536. if (__IsPixelFormat8(objIImageData.GetPixelFormat()))
  537. {
  538. byte[] byMonoBufferTmp = new byte[__GetStride(m_nWidth, m_bIsColor) * m_nHeight];
  539. Marshal.Copy(objIImageData.GetBuffer(), byMonoBufferTmp, 0, __GetStride(m_nWidth, m_bIsColor) * m_nHeight);
  540. pRaw8Buffer = objIImageData.GetBuffer();
  541. // 黑白相机需要翻转数据后显示
  542. for (int i = 0; i < m_nHeight; i++)
  543. {
  544. Buffer.BlockCopy(byMonoBufferTmp, (m_nHeight - i - 1) * m_nWidth, m_byMonoBuffer, i * m_nWidth, m_nWidth);
  545. }
  546. }
  547. else
  548. {
  549. // 设置目标像素格式
  550. m_objImageFormatConvert.SetDstFormat(GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO8);
  551. // 获取目标像素格式Buffer大小
  552. UInt64 i64DstBufferize = m_objImageFormatConvert.GetBufferSizeForConversion(objIImageData);
  553. // 设置目标有效位数
  554. m_objImageFormatConvert.SetValidBits(emValidBits);
  555. // 进行图像格式转换
  556. m_objImageFormatConvert.Convert(objIImageData, m_pOutBuffer, i64DstBufferize, true);
  557. Marshal.Copy(m_pOutBuffer, m_byMonoBuffer, 0, __GetStride(m_nWidth, m_bIsColor) * m_nHeight);
  558. pRaw8Buffer = m_pOutBuffer;
  559. }
  560. Image = ConvertImage((uint)m_nWidth, (uint)m_nHeight, pRaw8Buffer, GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO8);
  561. }
  562. }
  563. }
  564. if (Image != null)
  565. {
  566. ErrorMessage = "";
  567. TotalTime = sw.Elapsed;
  568. return Image;
  569. }
  570. }
  571. catch (Exception ex)
  572. {
  573. CloseDevice();
  574. OpenDevice();
  575. ErrorMessage = ex.Message;
  576. }
  577. finally
  578. {
  579. if (null != objIImageData)
  580. {
  581. //用完之后释放资源
  582. objIImageData.Destroy();
  583. }
  584. }
  585. }
  586. if (IsConnected)
  587. {
  588. IsConnected = false;
  589. CameraConnectChangedEvent?.Invoke(ID, false);
  590. }
  591. return null;
  592. }
  593. finally
  594. {
  595. ExitOperation();
  596. }
  597. }
  598. public bool OpenDevice()
  599. {
  600. EnterOperation();
  601. try
  602. {
  603. IsConnected = false;
  604. var list = GetDevices();
  605. foreach (var device in list)
  606. {
  607. if (device.CameraType == CameraType.GIGE)
  608. {
  609. if (IsFindByIp)
  610. {
  611. if (device.CameraIp == CameraIp)
  612. {
  613. IsHaveCamera = true;
  614. ManufacturerName = device.ManufacturerName;
  615. ModelName = device.Model;
  616. SerialNumber = device.SerialNumber;
  617. CameraType = CameraType.GIGE;
  618. break;
  619. }
  620. }
  621. else
  622. {
  623. if (device.SerialNumber == SerialNumber)
  624. {
  625. IsHaveCamera = true;
  626. ManufacturerName = device.ManufacturerName;
  627. ModelName = device.Model;
  628. SerialNumber = device.SerialNumber;
  629. CameraType = CameraType.GIGE;
  630. break;
  631. }
  632. }
  633. }
  634. else
  635. {
  636. if (device.SerialNumber == SerialNumber)
  637. {
  638. IsHaveCamera = true;
  639. ManufacturerName = device.ManufacturerName;
  640. ModelName = device.Model;
  641. SerialNumber = device.SerialNumber;
  642. CameraType = CameraType.GIGE;
  643. break;
  644. }
  645. }
  646. }
  647. if (!IsHaveCamera)
  648. {
  649. //throw new Exception("没有发现相机");
  650. return false;
  651. }
  652. // 如果设备已经打开则关闭,保证相机在初始化出错情况下能再次打开
  653. if (null != m_objIGXDevice)
  654. {
  655. m_objIGXDevice.Close();
  656. m_objIGXDevice = null;
  657. }
  658. //打开设备
  659. m_objIGXDevice = m_objIGXFactory.OpenDeviceBySN(SerialNumber, GxIAPINET.GX_ACCESS_MODE.GX_ACCESS_EXCLUSIVE);
  660. m_objIGXFeatureControl = m_objIGXDevice.GetRemoteFeatureControl();
  661. //打开流
  662. if (null != m_objIGXDevice)
  663. {
  664. m_objIGXStream = m_objIGXDevice.OpenStream(0);
  665. m_objIGXStreamFeatureControl = m_objIGXStream.GetFeatureControl();
  666. }
  667. // 建议用户在打开网络相机之后,根据当前网络环境设置相机的流通道包长值,
  668. // 以提高网络相机的采集性能,设置方法参考以下代码。
  669. GX_DEVICE_CLASS_LIST objDeviceClass = m_objIGXDevice.GetDeviceInfo().GetDeviceClass();
  670. if (GX_DEVICE_CLASS_LIST.GX_DEVICE_CLASS_GEV == objDeviceClass)
  671. {
  672. // 判断设备是否支持流通道数据包功能
  673. if (true == m_objIGXFeatureControl.IsImplemented("GevSCPSPacketSize"))
  674. {
  675. // 获取当前网络环境的最优包长值
  676. uint nPacketSize = m_objIGXStream.GetOptimalPacketSize();
  677. // 将最优包长值设置为当前设备的流通道包长值
  678. m_objIGXFeatureControl.GetIntFeature("GevSCPSPacketSize").SetValue(nPacketSize);
  679. }
  680. }
  681. //初始化相机参数
  682. if (null != m_objIGXFeatureControl)
  683. {
  684. //设置采集模式连续采集
  685. m_objIGXFeatureControl.GetEnumFeature("AcquisitionMode").SetValue("Continuous");
  686. //设置触发模式为关
  687. m_objIGXFeatureControl.GetEnumFeature("TriggerMode").SetValue("Off");
  688. }
  689. ReleaseBuffer();
  690. GxBitmap();
  691. if (null != m_objIGXStreamFeatureControl)
  692. {
  693. try
  694. {
  695. //设置流层Buffer处理模式为OldestFirst
  696. m_objIGXStreamFeatureControl.GetEnumFeature("StreamBufferHandlingMode").SetValue("OldestFirst");
  697. }
  698. catch (Exception)
  699. {
  700. }
  701. }
  702. if (!IsConnected)
  703. {
  704. CameraConnectChangedEvent?.Invoke(ID, true);
  705. }
  706. IsConnected = true;
  707. return IsConnected;
  708. }
  709. finally
  710. {
  711. ExitOperation();
  712. }
  713. }
  714. /// <summary>
  715. /// 打开相机异步
  716. /// </summary>
  717. /// <returns></returns>
  718. public Task<bool> OpenDeviceAsync()
  719. {
  720. return Task.Run(() =>
  721. {
  722. return OpenDevice();
  723. });
  724. }
  725. public bool SetExposureTime(float ExposureTime)
  726. {
  727. EnterOperation();
  728. try
  729. {
  730. if (null == m_objIGXFeatureControl)
  731. return false;
  732. if (GetExposureTime() != ExposureTime)
  733. {
  734. bool success = false;
  735. for (int i = 0; i < 5; i++)
  736. {
  737. m_objIGXFeatureControl.GetFloatFeature("ExposureTime").SetValue(ExposureTime);
  738. success = true;
  739. }
  740. return success;
  741. }
  742. return true;
  743. }
  744. finally
  745. {
  746. ExitOperation();
  747. }
  748. }
  749. public bool SetGain(float Gain)
  750. {
  751. EnterOperation();
  752. try
  753. {
  754. if (null == m_objIGXFeatureControl)
  755. return false;
  756. if (GetGain() != Gain)
  757. {
  758. bool success = false;
  759. for (int i = 0; i < 5; i++)
  760. {
  761. m_objIGXFeatureControl.GetFloatFeature("Gain").SetValue(Gain);
  762. success = true;
  763. }
  764. return success;
  765. }
  766. return true;
  767. }
  768. finally
  769. {
  770. ExitOperation();
  771. }
  772. }
  773. public void StartGrabbing()
  774. {
  775. lock (_stateLock)
  776. {
  777. if (IsGrabbing)
  778. return;
  779. IsGrabbing = true;
  780. }
  781. m_hReceiveThread = new Thread(GetStreamThreadProc) { IsBackground = true };
  782. m_hReceiveThread.Start();
  783. }
  784. public void StopGrabbing()
  785. {
  786. try
  787. {
  788. lock (_stateLock)
  789. {
  790. IsGrabbing = false;
  791. }
  792. Thread.Sleep(1000);
  793. if (m_hReceiveThread != null)
  794. {
  795. m_hReceiveThread.Abort();
  796. m_hReceiveThread = null;
  797. }
  798. }
  799. catch (Exception)
  800. {
  801. }
  802. }
  803. private void GetStreamThreadProc()
  804. {
  805. while (IsGrabbing)
  806. {
  807. try
  808. {
  809. Grab();
  810. ImageCallbackEvent?.Invoke(Image, TotalTime, ErrorMessage, ID);
  811. }
  812. catch (Exception)
  813. {
  814. }
  815. Thread.Sleep(10);
  816. }
  817. IsGrabbing = false;
  818. }
  819. #endregion
  820. #region method
  821. /// <summary>
  822. /// 初始化设备对象
  823. /// </summary>
  824. /// <param name="objIGXDevice">设备对象</param>
  825. public void GxBitmap()
  826. {
  827. // 初始化图像格式转换对象
  828. m_objImageFormatConvert = m_objIGXFactory.CreateImageFormatConvert();
  829. if (null != m_objIGXDevice)
  830. {
  831. m_nWidth = (int)m_objIGXDevice.GetRemoteFeatureControl().GetIntFeature("Width").GetValue();
  832. m_nHeight = (int)m_objIGXDevice.GetRemoteFeatureControl().GetIntFeature("Height").GetValue();
  833. ImageWidth = (uint)m_nWidth;
  834. ImageHeight = (uint)m_nHeight;
  835. //获取是否为彩色相机
  836. IsSupportColor(ref m_bIsColor);
  837. }
  838. //申请用于缓存图像数据的buffer
  839. m_byMonoBuffer = new byte[__GetStride(m_nWidth, m_bIsColor) * m_nHeight];
  840. m_byColorBuffer = new byte[__GetStride(m_nWidth, m_bIsColor) * m_nHeight];
  841. m_pOutBuffer = Marshal.AllocCoTaskMem(__GetStride(m_nWidth, m_bIsColor) * m_nHeight);
  842. if (m_bIsColor)
  843. {
  844. m_objBitmapInfo.bmiHeader.biSize = (uint)Marshal.SizeOf(typeof(CWin32Bitmaps.BITMAPINFOHEADER));
  845. m_objBitmapInfo.bmiHeader.biWidth = m_nWidth;
  846. m_objBitmapInfo.bmiHeader.biHeight = m_nHeight;
  847. m_objBitmapInfo.bmiHeader.biPlanes = 1;
  848. m_objBitmapInfo.bmiHeader.biBitCount = 24;
  849. m_objBitmapInfo.bmiHeader.biCompression = 0;
  850. m_objBitmapInfo.bmiHeader.biSizeImage = 0;
  851. m_objBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
  852. m_objBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
  853. m_objBitmapInfo.bmiHeader.biClrUsed = 0;
  854. m_objBitmapInfo.bmiHeader.biClrImportant = 0;
  855. }
  856. else
  857. {
  858. m_objBitmapInfo.bmiHeader.biSize = (uint)Marshal.SizeOf(typeof(CWin32Bitmaps.BITMAPINFOHEADER));
  859. m_objBitmapInfo.bmiHeader.biWidth = m_nWidth;
  860. m_objBitmapInfo.bmiHeader.biHeight = m_nHeight;
  861. m_objBitmapInfo.bmiHeader.biPlanes = 1;
  862. m_objBitmapInfo.bmiHeader.biBitCount = 8;
  863. m_objBitmapInfo.bmiHeader.biCompression = 0;
  864. m_objBitmapInfo.bmiHeader.biSizeImage = 0;
  865. m_objBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
  866. m_objBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
  867. m_objBitmapInfo.bmiHeader.biClrUsed = 0;
  868. m_objBitmapInfo.bmiHeader.biClrImportant = 0;
  869. m_objBitmapInfo.bmiColors = new CWin32Bitmaps.RGBQUAD[256];
  870. // 黑白图像需要初始化调色板
  871. for (int i = 0; i < 256; i++)
  872. {
  873. m_objBitmapInfo.bmiColors[i].rgbBlue = (byte)i;
  874. m_objBitmapInfo.bmiColors[i].rgbGreen = (byte)i;
  875. m_objBitmapInfo.bmiColors[i].rgbRed = (byte)i;
  876. m_objBitmapInfo.bmiColors[i].rgbReserved = 0;
  877. }
  878. }
  879. m_pBitmapInfo = Marshal.AllocHGlobal(2048);
  880. Marshal.StructureToPtr(m_objBitmapInfo, m_pBitmapInfo, false);
  881. }
  882. /// <summary>
  883. /// 释放buffer
  884. /// </summary>
  885. public void ReleaseBuffer()
  886. {
  887. // 释放输出Buffer内存
  888. if (m_pOutBuffer != IntPtr.Zero)
  889. {
  890. Marshal.FreeCoTaskMem(m_pOutBuffer);
  891. m_pOutBuffer = IntPtr.Zero;
  892. }
  893. if (m_pBitmapInfo != IntPtr.Zero)
  894. {
  895. Marshal.FreeHGlobal(m_pBitmapInfo);
  896. m_pBitmapInfo = IntPtr.Zero;
  897. }
  898. }
  899. /// <summary>
  900. /// 是否支持彩色
  901. /// </summary>
  902. /// <param name="bIsColorFilter">是否支持彩色</param>
  903. public void IsSupportColor(ref bool bIsColorFilter)
  904. {
  905. bool bIsImplemented = false;
  906. bool bIsMono = false;
  907. string strPixelFormat = "";
  908. uint nPixelFormatValue = 0;
  909. strPixelFormat = m_objIGXDevice.GetRemoteFeatureControl().GetEnumFeature("PixelFormat").GetValue();
  910. if (0 == string.Compare(strPixelFormat, 0, "Mono", 0, 4))
  911. {
  912. bIsMono = true;
  913. }
  914. else
  915. {
  916. bIsMono = false;
  917. }
  918. // 通过当前像素格式判断是否为彩色相机
  919. CDecide.GetConvertPixelFormat(strPixelFormat, ref nPixelFormatValue);
  920. bIsImplemented = CDecide.GetIsGray(nPixelFormatValue);
  921. if ((!bIsMono) && (!bIsImplemented))
  922. {
  923. bIsColorFilter = true;
  924. }
  925. else
  926. {
  927. bIsColorFilter = false;
  928. }
  929. }
  930. /// <summary>
  931. /// 计算宽度所占的字节数
  932. /// </summary>
  933. /// <param name="nWidth">图像宽度</param>
  934. /// <param name="bIsColor">是否是彩色相机</param>
  935. /// <returns>图像一行所占的字节数</returns>
  936. private int __GetStride(int nWidth, bool bIsColor)
  937. {
  938. return bIsColor ? nWidth * 3 : nWidth;
  939. }
  940. /// <summary>
  941. /// 通过GX_PIXEL_FORMAT_ENTRY获取最优Bit位
  942. /// </summary>
  943. /// <param name="em">图像数据格式</param>
  944. /// <returns>最优Bit位</returns>
  945. public GX_VALID_BIT_LIST GetBestValudBit(GX_PIXEL_FORMAT_ENTRY emPixelFormatEntry)
  946. {
  947. GX_VALID_BIT_LIST emValidBits = GX_VALID_BIT_LIST.GX_BIT_0_7;
  948. switch (emPixelFormatEntry)
  949. {
  950. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO8:
  951. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GR8:
  952. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_RG8:
  953. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GB8:
  954. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_BG8:
  955. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_RGB8:
  956. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BGR8:
  957. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_R8:
  958. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_G8:
  959. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_B8:
  960. {
  961. emValidBits = GX_VALID_BIT_LIST.GX_BIT_0_7;
  962. break;
  963. }
  964. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO10:
  965. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO10_P:
  966. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO10_PACKED:
  967. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GR10:
  968. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_RG10:
  969. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GB10:
  970. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_BG10:
  971. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_BG10_P:
  972. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_BG10_PACKED:
  973. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GB10_P:
  974. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GB10_PACKED:
  975. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GR10_P:
  976. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GR10_PACKED:
  977. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_RG10_P:
  978. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_RG10_PACKED:
  979. {
  980. emValidBits = GX_VALID_BIT_LIST.GX_BIT_2_9;
  981. break;
  982. }
  983. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO12:
  984. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO12_P:
  985. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO12_PACKED:
  986. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GR12:
  987. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_RG12:
  988. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GB12:
  989. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_BG12:
  990. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_BG12_P:
  991. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_BG12_PACKED:
  992. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GB12_P:
  993. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GB12_PACKED:
  994. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GR12_P:
  995. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GR12_PACKED:
  996. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_RG12_P:
  997. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_RG12_PACKED:
  998. {
  999. emValidBits = GX_VALID_BIT_LIST.GX_BIT_4_11;
  1000. break;
  1001. }
  1002. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO14:
  1003. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GR14:
  1004. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_RG14:
  1005. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GB14:
  1006. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_BG14:
  1007. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_BG14_P:
  1008. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GB14_P:
  1009. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GR14_P:
  1010. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_RG14_P:
  1011. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO14_P:
  1012. {
  1013. emValidBits = GX_VALID_BIT_LIST.GX_BIT_6_13;
  1014. break;
  1015. }
  1016. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO16:
  1017. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GR16:
  1018. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_RG16:
  1019. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_GB16:
  1020. case GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_BAYER_BG16:
  1021. {
  1022. emValidBits = GX_VALID_BIT_LIST.GX_BIT_8_15;
  1023. break;
  1024. }
  1025. default:
  1026. break;
  1027. }
  1028. return emValidBits;
  1029. }
  1030. /// <summary>
  1031. /// 判断PixelFormat是否为8位
  1032. /// </summary>
  1033. /// <param name="emPixelFormatEntry">图像数据格式</param>
  1034. /// <returns>true为8为数据,false为非8位数据</returns>
  1035. private bool __IsPixelFormat8(GX_PIXEL_FORMAT_ENTRY emPixelFormatEntry)
  1036. {
  1037. const uint PIXEL_FORMATE_BIT = 0x00FF0000; //用于与当前的数据格式进行与运算得到当前的数据位数
  1038. const uint GX_PIXEL_8BIT = 0x00080000; //8位数据图像格式
  1039. bool bIsPixelFormat8 = false;
  1040. uint uiPixelFormatEntry = (uint)emPixelFormatEntry;
  1041. if ((uiPixelFormatEntry & PIXEL_FORMATE_BIT) == GX_PIXEL_8BIT)
  1042. {
  1043. bIsPixelFormat8 = true;
  1044. }
  1045. return bIsPixelFormat8;
  1046. }
  1047. /// <summary>
  1048. /// 转换图片
  1049. /// </summary>
  1050. /// <param name="nHeight">高</param>
  1051. /// <param name="nWidth">宽</param>
  1052. /// <param name="pImageBuf">图片数据</param>
  1053. /// <param name="enPixelType">像素格式</param>
  1054. public ICogImage ConvertImage(UInt32 nWidth, UInt32 nHeight, IntPtr pImageBuf, GX_PIXEL_FORMAT_ENTRY enPixelType)
  1055. {
  1056. try
  1057. {
  1058. if (enPixelType == GX_PIXEL_FORMAT_ENTRY.GX_PIXEL_FORMAT_MONO8)
  1059. {
  1060. CogImage8Root cogImage8Root = new CogImage8Root();
  1061. cogImage8Root.Initialize((Int32)nWidth, (Int32)nHeight, pImageBuf, (Int32)nWidth, null);
  1062. CogImage8Grey cogImage8Grey = new CogImage8Grey();
  1063. cogImage8Grey.SetRoot(cogImage8Root);
  1064. var image = cogImage8Grey.ScaleImage((int)nWidth, (int)nHeight);
  1065. System.GC.Collect();
  1066. return image;
  1067. }
  1068. else
  1069. {
  1070. int stride = (int)nWidth * 3;
  1071. CogImage24PlanarColor cogImage24PlanarColor = new CogImage24PlanarColor(new Bitmap((int)nWidth, (int)nHeight, stride, PixelFormat.Format24bppRgb, pImageBuf));
  1072. var m_InputImageRgb24 = cogImage24PlanarColor.Copy(CogImageCopyModeConstants.CopyPixels);
  1073. return m_InputImageRgb24;
  1074. }
  1075. }
  1076. catch (System.Exception)
  1077. {
  1078. return null;
  1079. }
  1080. }
  1081. #endregion
  1082. #region 属性通知
  1083. /// <summary>
  1084. /// Occurs when a property value changes.
  1085. /// </summary>
  1086. public event PropertyChangedEventHandler PropertyChanged;
  1087. /// <summary>
  1088. /// Checks if a property already matches a desired value. Sets the property and
  1089. /// notifies listeners only when necessary.
  1090. /// </summary>
  1091. /// <typeparam name="T">Type of the property.</typeparam>
  1092. /// <param name="storage">Reference to a property with both getter and setter.</param>
  1093. /// <param name="value">Desired value for the property.</param>
  1094. /// <param name="propertyName">Name of the property used to notify listeners. This
  1095. /// value is optional and can be provided automatically when invoked from compilers that
  1096. /// support CallerMemberName.</param>
  1097. /// <returns>True if the value was changed, false if the existing value matched the
  1098. /// desired value.</returns>
  1099. protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
  1100. {
  1101. if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
  1102. storage = value;
  1103. RaisePropertyChanged(propertyName);
  1104. return true;
  1105. }
  1106. /// <summary>
  1107. /// Checks if a property already matches a desired value. Sets the property and
  1108. /// notifies listeners only when necessary.
  1109. /// </summary>
  1110. /// <typeparam name="T">Type of the property.</typeparam>
  1111. /// <param name="storage">Reference to a property with both getter and setter.</param>
  1112. /// <param name="value">Desired value for the property.</param>
  1113. /// <param name="propertyName">Name of the property used to notify listeners. This
  1114. /// value is optional and can be provided automatically when invoked from compilers that
  1115. /// support CallerMemberName.</param>
  1116. /// <param name="onChanged">Action that is called after the property value has been changed.</param>
  1117. /// <returns>True if the value was changed, false if the existing value matched the
  1118. /// desired value.</returns>
  1119. protected virtual bool SetProperty<T>(ref T storage, T value, Action onChanged, [CallerMemberName] string propertyName = null)
  1120. {
  1121. if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
  1122. storage = value;
  1123. onChanged?.Invoke();
  1124. RaisePropertyChanged(propertyName);
  1125. return true;
  1126. }
  1127. /// <summary>
  1128. /// Raises this object's PropertyChanged event.
  1129. /// </summary>
  1130. /// <param name="propertyName">Name of the property used to notify listeners. This
  1131. /// value is optional and can be provided automatically when invoked from compilers
  1132. /// that support <see cref="CallerMemberNameAttribute"/>.</param>
  1133. protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
  1134. {
  1135. OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
  1136. }
  1137. /// <summary>
  1138. /// Raises this object's PropertyChanged event.
  1139. /// </summary>
  1140. /// <param name="args">The PropertyChangedEventArgs</param>
  1141. protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
  1142. {
  1143. PropertyChanged?.Invoke(this, args);
  1144. }
  1145. #endregion
  1146. }
  1147. }