ShowVisionRender.xaml.cs 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. using Cognex.VisionPro;
  2. using Cognex.VisionPro.ImageFile;
  3. using Cognex.VisionPro3D;
  4. using log4net.Core;
  5. using MahApps.Metro.Controls;
  6. using Prism.Events;
  7. using Prism.Ioc;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Drawing;
  11. using System.IO;
  12. using System.Threading.Tasks;
  13. using System.Windows;
  14. using System.Windows.Controls;
  15. using System.Windows.Forms.Integration;
  16. using System.Windows.Interop;
  17. using TeamAAS_VP;
  18. using TeamAAS_VP.Core;
  19. using TeamAAS_VP.Enums;
  20. using TeamAAS_VP.Events;
  21. using TeamAAS_VP.Interfaces;
  22. using TeamAAS_VP.Models;
  23. using TeamAAS_VP.Resources.Languages;
  24. using TeamAAS_VP.ViewModels;
  25. using TeamAAS_VP.ViewModels.Home;
  26. using static MaterialDesignThemes.Wpf.Theme.ToolBar;
  27. namespace TeamAAS_VP.Views.Home
  28. {
  29. /// <summary>
  30. /// Interaction logic for ShowVisionRender
  31. /// </summary>
  32. public partial class ShowVisionRender : UserControl
  33. {
  34. private const string Render2DKeySuffix = ":2D";
  35. private const string Render3DKeySuffix = ":3D";
  36. private static string Get2DKey(Guid id) => id.ToString() + Render2DKeySuffix;
  37. private static string Get3DKey(Guid id) => id.ToString() + Render3DKeySuffix;
  38. ShowVisionRenderViewModel viewModel;
  39. Dictionary<string, WindowsFormsHost> vmRenders;
  40. Dictionary<Guid, TextBlock> Titles;
  41. IEventAggregator _eventAggregator;
  42. private readonly IProductService _productService;
  43. public ShowVisionRender()
  44. {
  45. InitializeComponent();
  46. vmRenders = new Dictionary<string, WindowsFormsHost>();
  47. Titles = new Dictionary<Guid, TextBlock>();
  48. viewModel = DataContext as ShowVisionRenderViewModel;
  49. _eventAggregator = viewModel._eventAggregator;
  50. _productService = ((Prism.PrismApplicationBase)App.Current).Container.Resolve<IProductService>();
  51. viewModel.UpdateLayout += ViewModel_UpdateLayout;
  52. _eventAggregator.GetEvent<RenderUpdateNotification>().Subscribe(UpdateRenderModuleSource);
  53. _eventAggregator.GetEvent<ProductChangedNotification>().Subscribe(ProductChanged);
  54. }
  55. private bool GetView3DUse()
  56. {
  57. try
  58. {
  59. var configService = ((Prism.PrismApplicationBase)App.Current).Container.Resolve<IConfigService>();
  60. if(configService.GetSystemConfiguration().PickPointNum==0)
  61. {
  62. return false;
  63. }
  64. else
  65. {
  66. return true;
  67. }
  68. //return true;
  69. }
  70. catch
  71. {
  72. return false;
  73. }
  74. }
  75. private void UpdateRenderModuleSource(ShowRender render)
  76. {
  77. //foreach (var item in vmRenders)
  78. //{
  79. // if (item.Key== render.Id)
  80. // {
  81. // App.Current.Dispatcher.Invoke(new Action(() =>
  82. // {
  83. // item.Value.ModuleSource = render.ModuleSource;
  84. // }));
  85. // break;
  86. // }
  87. //}
  88. this.gridRender.Dispatcher.BeginInvoke(new Action(() =>
  89. {
  90. if (render == null)
  91. return;
  92. if (render.Is3DModel == true)
  93. {
  94. if (!GetView3DUse())
  95. return;
  96. if (!vmRenders.TryGetValue(Get3DKey(render.Id), out var host))
  97. return;
  98. var display = host.Child as Cognex.VisionPro3D.Cog3DDisplayV2WF;
  99. if (display == null)
  100. return;
  101. try
  102. {
  103. display.Clear();
  104. if (render.RangeImage == null || render.GreyImage == null)
  105. return;
  106. var rImgG = new Cog3DRangeImageGraphic(render.RangeImage, render.GreyImage);
  107. display.Add(rImgG, "__default");
  108. display.FitView();
  109. }
  110. catch (System.Windows.Forms.AxHost.InvalidActiveXStateException)
  111. {
  112. }
  113. //return;
  114. }
  115. if (!vmRenders.TryGetValue(Get2DKey(render.Id), out var host2D))
  116. return;
  117. var recordDisplay = host2D.Child as Cognex.VisionPro.CogRecordDisplay;
  118. if (recordDisplay == null)
  119. return;
  120. try
  121. {
  122. recordDisplay.Record = null;
  123. recordDisplay.Image = render.Image;
  124. recordDisplay.StaticGraphics.Clear();
  125. if (render.Graphic != null)
  126. recordDisplay.StaticGraphics.AddList(render.Graphic, "");
  127. if (render.Record != null)
  128. recordDisplay.Record = render.Record;
  129. }
  130. catch (System.Windows.Forms.AxHost.InvalidActiveXStateException)
  131. {
  132. }
  133. }));
  134. }
  135. private void AddRenderPair(Guid id, string displayName)
  136. {
  137. // 2D
  138. var display2D = new Cognex.VisionPro.CogRecordDisplay() { Tag = displayName };
  139. display2D.HandleCreated += (s, e) =>
  140. {
  141. try
  142. {
  143. display2D.HorizontalScrollBar = false;
  144. display2D.VerticalScrollBar = false;
  145. display2D.AutoFit = true;
  146. display2D.BackColor = System.Drawing.SystemColors.ActiveCaption;
  147. }
  148. catch (System.Windows.Forms.AxHost.InvalidActiveXStateException)
  149. {
  150. }
  151. };
  152. vmRenders.Add(Get2DKey(id), new WindowsFormsHost() { Tag = displayName, Child = display2D });
  153. // 3D:按配置创建
  154. if (!GetView3DUse())
  155. return;
  156. // 3D
  157. var display3D = new Cognex.VisionPro3D.Cog3DDisplayV2WF() { Tag = displayName };
  158. display3D.HandleCreated += (s, e) =>
  159. {
  160. try
  161. {
  162. display3D.BackColor = System.Drawing.SystemColors.ActiveCaption;
  163. }
  164. catch (System.Windows.Forms.AxHost.InvalidActiveXStateException)
  165. {
  166. }
  167. };
  168. vmRenders.Add(Get3DKey(id), new WindowsFormsHost() { Tag = displayName, Child = display3D });
  169. }
  170. private Grid CreateCellGrid(Guid id, string displayName, System.Windows.Media.FontFamily font)
  171. {
  172. var is3DEnabled = GetView3DUse();
  173. var cell = new Grid();
  174. cell.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
  175. cell.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  176. var title = new TextBlock()
  177. {
  178. Text = displayName,
  179. HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
  180. FontWeight = FontWeights.Bold,
  181. FontFamily = font,
  182. FontSize = 12,
  183. Foreground = System.Windows.Media.Brushes.Black
  184. };
  185. Titles[id] = title;
  186. var content = new Grid();
  187. if(is3DEnabled)
  188. {
  189. content.ColumnDefinitions.Add(new ColumnDefinition()); // 2D
  190. content.ColumnDefinitions.Add(new ColumnDefinition()); // 3D
  191. content.Children.Add(vmRenders[Get2DKey(id)]);
  192. content.Children.Add(vmRenders[Get3DKey(id)]);
  193. Grid.SetColumn(vmRenders[Get2DKey(id)], 0);
  194. Grid.SetColumn(vmRenders[Get3DKey(id)], 1);
  195. }
  196. else
  197. {
  198. content.ColumnDefinitions.Add(new ColumnDefinition()); // 仅 2D
  199. content.Children.Add(vmRenders[Get2DKey(id)]);
  200. Grid.SetColumn(vmRenders[Get2DKey(id)], 0);
  201. }
  202. cell.Children.Add(title);
  203. cell.Children.Add(content);
  204. Grid.SetRow(title, 0);
  205. Grid.SetRow(content, 1);
  206. return cell;
  207. }
  208. Grid grid1 = new Grid();
  209. Grid grid2 = new Grid();
  210. Grid grid3 = new Grid();
  211. Grid grid4 = new Grid();
  212. Grid grid5 = new Grid();
  213. Grid grid6 = new Grid();
  214. Grid grid7 = new Grid();
  215. Grid grid8 = new Grid();
  216. Grid grid9 = new Grid();
  217. Grid grid10 = new Grid();
  218. Grid grid11 = new Grid();
  219. Grid grid12 = new Grid();
  220. Grid grid13 = new Grid();
  221. Grid grid14 = new Grid();
  222. Grid grid15 = new Grid();
  223. Grid grid16 = new Grid();
  224. Grid grid17 = new Grid();
  225. Grid grid18 = new Grid();
  226. Grid grid19 = new Grid();
  227. Grid grid20 = new Grid();
  228. private void ViewModel_UpdateLayout(System.Collections.ObjectModel.ObservableCollection<Models.ShowRender> obj)
  229. {
  230. System.Windows.Media.FontFamily font = Application.Current.Resources["DefaultFont"] as System.Windows.Media.FontFamily;
  231. if (vmRenders.Count > 0)
  232. {
  233. foreach (var render in vmRenders)
  234. {
  235. render.Value.Dispose();
  236. }
  237. }
  238. vmRenders.Clear();
  239. gridRender.Children.Clear();
  240. gridRender.RowDefinitions.Clear();
  241. gridRender.ColumnDefinitions.Clear();
  242. Titles.Clear();
  243. if (obj == null || obj.Count == 0)
  244. return;
  245. // 先创建所有相机的 2D/3D 对
  246. for (int i = 0; i < obj.Count; i++)
  247. AddRenderPair(obj[i].Id, obj[i].DisplayName);
  248. switch (obj.Count)
  249. {
  250. case 1:
  251. {
  252. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  253. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  254. var cell = CreateCellGrid(obj[0].Id, obj[0].DisplayName, font);
  255. gridRender.Children.Add(cell);
  256. Grid.SetRow(cell, 0);
  257. Grid.SetColumn(cell, 0);
  258. gridRender.ShowGridLines = false;
  259. break;
  260. }
  261. case 2:
  262. {
  263. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  264. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  265. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  266. gridRender.ShowGridLines = true;
  267. var cell0 = CreateCellGrid(obj[0].Id, obj[0].DisplayName, font);
  268. var cell1 = CreateCellGrid(obj[1].Id, obj[1].DisplayName, font);
  269. gridRender.Children.Add(cell0);
  270. gridRender.Children.Add(cell1);
  271. Grid.SetRow(cell0, 0);
  272. Grid.SetColumn(cell0, 0);
  273. Grid.SetRow(cell1, 0);
  274. Grid.SetColumn(cell1, 1);
  275. break;
  276. }
  277. case 3:
  278. {
  279. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  280. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  281. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  282. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  283. gridRender.ShowGridLines = true;
  284. var cell0 = CreateCellGrid(obj[0].Id, obj[0].DisplayName, font);
  285. var cell1 = CreateCellGrid(obj[1].Id, obj[1].DisplayName, font);
  286. var cell2 = CreateCellGrid(obj[2].Id, obj[2].DisplayName, font);
  287. gridRender.Children.Add(cell0);
  288. gridRender.Children.Add(cell1);
  289. gridRender.Children.Add(cell2);
  290. Grid.SetRow(cell0, 0);
  291. Grid.SetColumn(cell0, 0);
  292. Grid.SetRow(cell1, 0);
  293. Grid.SetColumn(cell1, 1);
  294. Grid.SetRow(cell2, 1);
  295. Grid.SetColumn(cell2, 0);
  296. Grid.SetColumnSpan(cell2, 2);
  297. break;
  298. }
  299. case 4:
  300. {
  301. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  302. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  303. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  304. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  305. gridRender.ShowGridLines = true;
  306. for (int i = 0; i < 4; i++)
  307. {
  308. var cell = CreateCellGrid(obj[i].Id, obj[i].DisplayName, font);
  309. gridRender.Children.Add(cell);
  310. Grid.SetRow(cell, i / 2);
  311. Grid.SetColumn(cell, i % 2);
  312. }
  313. break;
  314. }
  315. case 5:
  316. {
  317. // 你的原布局:上面2个,下面3个(通过嵌套grid6)
  318. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  319. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  320. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  321. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  322. gridRender.ShowGridLines = true;
  323. var top0 = CreateCellGrid(obj[0].Id, obj[0].DisplayName, font);
  324. var top1 = CreateCellGrid(obj[1].Id, obj[1].DisplayName, font);
  325. var bottom = new Grid();
  326. bottom.ColumnDefinitions.Add(new ColumnDefinition());
  327. bottom.ColumnDefinitions.Add(new ColumnDefinition());
  328. bottom.ColumnDefinitions.Add(new ColumnDefinition());
  329. var b0 = CreateCellGrid(obj[2].Id, obj[2].DisplayName, font);
  330. var b1 = CreateCellGrid(obj[3].Id, obj[3].DisplayName, font);
  331. var b2 = CreateCellGrid(obj[4].Id, obj[4].DisplayName, font);
  332. bottom.Children.Add(b0);
  333. bottom.Children.Add(b1);
  334. bottom.Children.Add(b2);
  335. Grid.SetColumn(b0, 0);
  336. Grid.SetColumn(b1, 1);
  337. Grid.SetColumn(b2, 2);
  338. gridRender.Children.Add(top0);
  339. gridRender.Children.Add(top1);
  340. gridRender.Children.Add(bottom);
  341. Grid.SetRow(top0, 0);
  342. Grid.SetColumn(top0, 0);
  343. Grid.SetRow(top1, 0);
  344. Grid.SetColumn(top1, 1);
  345. Grid.SetRow(bottom, 1);
  346. Grid.SetColumn(bottom, 0);
  347. Grid.SetColumnSpan(bottom, 2);
  348. break;
  349. }
  350. case 6:
  351. {
  352. // 你的原布局:2行3列
  353. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  354. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  355. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  356. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  357. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  358. gridRender.ShowGridLines = true;
  359. for (int i = 0; i < 6; i++)
  360. {
  361. var cell = CreateCellGrid(obj[i].Id, obj[i].DisplayName, font);
  362. gridRender.Children.Add(cell);
  363. Grid.SetRow(cell, i / 3);
  364. Grid.SetColumn(cell, i % 3);
  365. }
  366. break;
  367. }
  368. case 7:
  369. {
  370. // 你的原布局:第一行4个,第二行3个(但原来只放到 col 0/1/2)
  371. // 这里保持原样:第一行4列,第二行3列(第4列留空)
  372. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  373. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  374. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  375. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  376. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  377. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  378. gridRender.ShowGridLines = true;
  379. for (int i = 0; i < 7; i++)
  380. {
  381. var cell = CreateCellGrid(obj[i].Id, obj[i].DisplayName, font);
  382. gridRender.Children.Add(cell);
  383. if (i < 4)
  384. {
  385. Grid.SetRow(cell, 0);
  386. Grid.SetColumn(cell, i);
  387. }
  388. else
  389. {
  390. Grid.SetRow(cell, 1);
  391. Grid.SetColumn(cell, i - 4);
  392. }
  393. }
  394. break;
  395. }
  396. case 8:
  397. {
  398. // 2行4列
  399. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  400. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  401. for (int i = 0; i < 4; i++)
  402. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  403. gridRender.ShowGridLines = true;
  404. for (int i = 0; i < 8; i++)
  405. {
  406. var cell = CreateCellGrid(obj[i].Id, obj[i].DisplayName, font);
  407. gridRender.Children.Add(cell);
  408. Grid.SetRow(cell, i / 4);
  409. Grid.SetColumn(cell, i % 4);
  410. }
  411. break;
  412. }
  413. case 9:
  414. {
  415. // 3行3列
  416. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  417. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  418. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  419. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  420. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  421. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  422. gridRender.ShowGridLines = true;
  423. for (int i = 0; i < 9; i++)
  424. {
  425. var cell = CreateCellGrid(obj[i].Id, obj[i].DisplayName, font);
  426. gridRender.Children.Add(cell);
  427. Grid.SetRow(cell, i / 3);
  428. Grid.SetColumn(cell, i % 3);
  429. }
  430. break;
  431. }
  432. case 12:
  433. {
  434. // 3行4列
  435. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  436. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  437. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  438. for (int i = 0; i < 4; i++)
  439. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  440. gridRender.ShowGridLines = true;
  441. for (int i = 0; i < 12; i++)
  442. {
  443. var cell = CreateCellGrid(obj[i].Id, obj[i].DisplayName, font);
  444. gridRender.Children.Add(cell);
  445. Grid.SetRow(cell, i / 4);
  446. Grid.SetColumn(cell, i % 4);
  447. }
  448. break;
  449. }
  450. case 20:
  451. {
  452. // 5行4列
  453. for (int r = 0; r < 5; r++)
  454. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  455. for (int c = 0; c < 4; c++)
  456. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  457. gridRender.ShowGridLines = true;
  458. for (int i = 0; i < 20; i++)
  459. {
  460. var cell = CreateCellGrid(obj[i].Id, obj[i].DisplayName, font);
  461. gridRender.Children.Add(cell);
  462. Grid.SetRow(cell, i / 4);
  463. Grid.SetColumn(cell, i % 4);
  464. }
  465. break;
  466. }
  467. default:
  468. {
  469. // 未覆盖的数量:先用简单的 1列多行兜底(避免空白)
  470. gridRender.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  471. gridRender.ColumnDefinitions.Add(new ColumnDefinition());
  472. gridRender.ShowGridLines = false;
  473. var cell = CreateCellGrid(obj[0].Id, obj[0].DisplayName, font);
  474. gridRender.Children.Add(cell);
  475. Grid.SetRow(cell, 0);
  476. Grid.SetColumn(cell, 0);
  477. break;
  478. }
  479. }
  480. }
  481. /// <summary>
  482. /// 保存图像(保持你原有逻辑不变,补充 Dispose 兜底,防止压缩分支不释放导致闪退)
  483. /// </summary>
  484. private void SaveImage(ProcedureSaveImageModel saveImageModel, ProcedureSaveImagePathModel saveImagePathModel, string path, ICogImage image, Bitmap reimage, bool result, bool isCompress, string imageFileName,bool is3Dmodel)
  485. {
  486. if (string.IsNullOrEmpty(path) || string.IsNullOrWhiteSpace(path) || !Path.IsPathRooted(path))
  487. {
  488. _eventAggregator.GetEvent<TaskMessageNotification>()
  489. .Publish(new Models.MessageStruct() { Message = "保存图像路径为无效的路径!", level = MessageLevel.Alarm });
  490. return;
  491. }
  492. Task.Run(() =>
  493. {
  494. try
  495. {
  496. DateTime now = DateTime.Now;
  497. //图片名
  498. string imgName = now.ToString("yyyy-MM-dd HH_mm_ss");
  499. if (!string.IsNullOrEmpty(imageFileName))
  500. {
  501. imgName = imageFileName;
  502. }
  503. if (saveImageModel == ProcedureSaveImageModel.Original)
  504. {
  505. string Originalpath = $"{path}\\{now:yyyy-MM}\\{now:MM-dd}\\{imgName}.bmp";
  506. if (saveImagePathModel == ProcedureSaveImagePathModel.Month_Day_OkNG_Time)
  507. {
  508. Originalpath = result
  509. ? $"{path}\\{now:yyyy-MM}\\{now:MM-dd}\\OK\\{imgName}.bmp"
  510. : $"{path}\\{now:yyyy-MM}\\{now:MM-dd}\\NG\\{imgName}.bmp";
  511. }
  512. else if (saveImagePathModel == ProcedureSaveImagePathModel.Month_Day_Ok_Time)
  513. {
  514. if (result)
  515. Originalpath = $"{path}\\{now:yyyy-MM}\\{now:MM-dd}\\OK\\{imgName}.bmp";
  516. else
  517. return;
  518. }
  519. else if (saveImagePathModel == ProcedureSaveImagePathModel.Month_Day_Ng_Time)
  520. {
  521. if (!result)
  522. Originalpath = $"{path}\\{now:yyyy-MM}\\{now:MM-dd}\\NG\\{imgName}.bmp";
  523. else
  524. return;
  525. }
  526. else if (saveImagePathModel == ProcedureSaveImagePathModel.Month_Day_Formula_ProductSN_Time)
  527. {
  528. // 当前产品配方名(过滤非法字符)
  529. string formulaName = _productService.GetCurrentProduct().Name;
  530. foreach (char c in Path.GetInvalidFileNameChars())
  531. formulaName = formulaName.Replace(c, '_');
  532. // 产品SN(过滤非法字符)
  533. string productSN = _productService.CurrentProductCode;
  534. foreach (char c in Path.GetInvalidFileNameChars())
  535. productSN = productSN.Replace(c, '_');
  536. string resultStr = result ? "OK" : "NG";
  537. Originalpath = $"{path}\\{now:yyyy-MM}\\{now:MM-dd}\\{formulaName}\\{productSN}\\{resultStr}\\{imgName}.bmp";
  538. }
  539. if (!Directory.Exists(Path.GetDirectoryName(Originalpath)))
  540. Directory.CreateDirectory(Path.GetDirectoryName(Originalpath));
  541. using (CogImageFileBMP _cogImageFileTool = new CogImageFileBMP())
  542. {
  543. _cogImageFileTool.Open(Originalpath, CogImageFileModeConstants.Write);
  544. _cogImageFileTool.Append(image);
  545. _cogImageFileTool.Close();
  546. }
  547. }
  548. else if (saveImageModel == ProcedureSaveImageModel.Recorded)
  549. {
  550. string Recordedpath = $"{path}\\{now:yyyy-MM}\\{now:MM-dd}\\{imgName}.bmp";
  551. if (saveImagePathModel == ProcedureSaveImagePathModel.Month_Day_OkNG_Time)
  552. {
  553. Recordedpath = result
  554. ? $"{path}\\{now:yyyy-MM}\\{now:MM-dd}\\OK\\{imgName}.bmp"
  555. : $"{path}\\{now:yyyy-MM}\\{now:MM-dd}\\NG\\{imgName}.bmp";
  556. }
  557. else if (saveImagePathModel == ProcedureSaveImagePathModel.Month_Day_Ok_Time)
  558. {
  559. if (result)
  560. Recordedpath = $"{path}\\{now:yyyy-MM}\\{now:MM-dd}\\OK\\{imgName}.bmp";
  561. else
  562. return;
  563. }
  564. else if (saveImagePathModel == ProcedureSaveImagePathModel.Month_Day_Ng_Time)
  565. {
  566. if (!result)
  567. Recordedpath = $"{path}\\{now:yyyy-MM}\\{now:MM-dd}\\NG\\{imgName}.bmp";
  568. else
  569. return;
  570. }
  571. else if (saveImagePathModel == ProcedureSaveImagePathModel.Month_Day_Formula_ProductSN_Time)
  572. {
  573. string formulaName = _productService.GetCurrentProduct().Name;
  574. foreach (char c in Path.GetInvalidFileNameChars())
  575. formulaName = formulaName.Replace(c, '_');
  576. string productSN = _productService.CurrentProductCode;
  577. foreach (char c in Path.GetInvalidFileNameChars())
  578. productSN = productSN.Replace(c, '_');
  579. string resultStr = result ? "OK" : "NG";
  580. Recordedpath = $"{path}\\{now:yyyy-MM}\\{now:MM-dd}\\{formulaName}\\{productSN}\\{resultStr}\\{imgName}.bmp";
  581. }
  582. if (!Directory.Exists(Path.GetDirectoryName(Recordedpath)))
  583. Directory.CreateDirectory(Path.GetDirectoryName(Recordedpath));
  584. if (isCompress)
  585. {
  586. ImageHelper.CompressImage(reimage, Recordedpath, 100);
  587. }
  588. else
  589. {
  590. reimage.Save(Recordedpath);
  591. }
  592. }
  593. else if (saveImageModel == ProcedureSaveImageModel.OriginalAndRecorded)
  594. {
  595. string Originalpath = "";
  596. if (is3Dmodel==true)
  597. {
  598. Originalpath = $"{path}\\Original\\{now:yyyy-MM}\\{now:MM-dd}\\{imgName}.idb";
  599. }
  600. else
  601. {
  602. Originalpath = $"{path}\\Original\\{now:yyyy-MM}\\{now:MM-dd}\\{imgName}.bmp";
  603. }
  604. string Recordedpath = $"{path}\\Recored\\{now:yyyy-MM}\\{now:MM-dd}\\{imgName}.bmp";
  605. if (saveImagePathModel == ProcedureSaveImagePathModel.Month_Day_OkNG_Time)
  606. {
  607. if (result)
  608. {
  609. Originalpath = $"{path}\\Original\\{now:yyyy-MM}\\{now:MM-dd}\\OK\\{imgName}.bmp";
  610. Recordedpath = $"{path}\\Recored\\{now:yyyy-MM}\\{now:MM-dd}\\OK\\{imgName}.bmp";
  611. }
  612. else
  613. {
  614. Originalpath = $"{path}\\Original\\{now:yyyy-MM}\\{now:MM-dd}\\NG\\{imgName}.bmp";
  615. Recordedpath = $"{path}\\Recored\\{now:yyyy-MM}\\{now:MM-dd}\\NG\\{imgName}.bmp";
  616. }
  617. }
  618. else if (saveImagePathModel == ProcedureSaveImagePathModel.Month_Day_Ok_Time)
  619. {
  620. if (result)
  621. {
  622. Originalpath = $"{path}\\Original\\{now:yyyy-MM}\\{now:MM-dd}\\OK\\{imgName}.bmp";
  623. Recordedpath = $"{path}\\Recored\\{now:yyyy-MM}\\{now:MM-dd}\\OK\\{imgName}.bmp";
  624. }
  625. else
  626. {
  627. return;
  628. }
  629. }
  630. else if (saveImagePathModel == ProcedureSaveImagePathModel.Month_Day_Ng_Time)
  631. {
  632. if (!result)
  633. {
  634. Originalpath = $"{path}\\Original\\{now:yyyy-MM}\\{now:MM-dd}\\NG\\{imgName}.bmp";
  635. Recordedpath = $"{path}\\Recored\\{now:yyyy-MM}\\{now:MM-dd}\\NG\\{imgName}.bmp";
  636. }
  637. else
  638. {
  639. return;
  640. }
  641. }
  642. else if (saveImagePathModel == ProcedureSaveImagePathModel.Month_Day_Formula_ProductSN_Time)
  643. {
  644. string formulaName = _productService.GetCurrentProduct().Name;
  645. foreach (char c in Path.GetInvalidFileNameChars())
  646. formulaName = formulaName.Replace(c, '_');
  647. string productSN = _productService.CurrentProductCode;
  648. if(productSN!=null )
  649. {
  650. foreach (char c in Path.GetInvalidFileNameChars())
  651. productSN = productSN.Replace(c, '_');
  652. }
  653. string resultStr = result ? "OK" : "NG";
  654. if (is3Dmodel == true)
  655. {
  656. Originalpath = $"{path}\\Original\\{now:yyyy-MM}\\{now:MM-dd}\\{formulaName}\\{productSN}\\{resultStr}\\{imgName}.idb";
  657. //Originalpath = $"{path}\\Original\\{now:yyyy-MM}\\{now:MM-dd}\\{imgName}.idb";
  658. }
  659. else
  660. {
  661. Originalpath = $"{path}\\Original\\{now:yyyy-MM}\\{now:MM-dd}\\{formulaName}\\{productSN}\\{resultStr}\\{imgName}.bmp";
  662. //Originalpath = $"{path}\\Original\\{now:yyyy-MM}\\{now:MM-dd}\\{imgName}.bmp";
  663. }
  664. Recordedpath = $"{path}\\Recored\\{now:yyyy-MM}\\{now:MM-dd}\\{formulaName}\\{productSN}\\{resultStr}\\{imgName}.bmp";
  665. }
  666. if (!Directory.Exists(Path.GetDirectoryName(Originalpath)))
  667. Directory.CreateDirectory(Path.GetDirectoryName(Originalpath));
  668. //using (CogImageFileBMP _cogImageFileTool = new CogImageFileBMP())
  669. //{
  670. // _cogImageFileTool.Open(Originalpath, CogImageFileModeConstants.Write);
  671. // _cogImageFileTool.Append(image);
  672. // _cogImageFileTool.Close();
  673. //}
  674. using (CogImageFile _cogImageFileTool = new CogImageFile())
  675. {
  676. _cogImageFileTool.Open(Originalpath, CogImageFileModeConstants.Write);
  677. _cogImageFileTool.Append(image);
  678. _cogImageFileTool.Close();
  679. }
  680. if (!Directory.Exists(Path.GetDirectoryName(Recordedpath)))
  681. Directory.CreateDirectory(Path.GetDirectoryName(Recordedpath));
  682. if (isCompress)
  683. {
  684. ImageHelper.CompressImage(reimage, Recordedpath, 100);
  685. }
  686. else
  687. {
  688. reimage.Save(Recordedpath);
  689. }
  690. }
  691. }
  692. catch (Exception ex)
  693. {
  694. LogHelper.WriteLogError("保存流程运行结果的图片时出错!", ex);
  695. }
  696. finally
  697. {
  698. // ======================= 【关键修复】无论是否压缩都释放Bitmap =======================
  699. try { reimage?.Dispose(); } catch { }
  700. }
  701. });
  702. }
  703. private void ProductChanged(ProductModel product)
  704. {
  705. this.gridRender.Dispatcher.BeginInvoke(new Action(() =>
  706. {
  707. var is3DEnabled = GetView3DUse();
  708. foreach (var item in vmRenders)
  709. {
  710. try
  711. {
  712. // 2D:永远清理
  713. var display2D = item.Value.Child as Cognex.VisionPro.CogRecordDisplay;
  714. if (display2D != null)
  715. {
  716. display2D.Record = null;
  717. display2D.Image = null;
  718. display2D.StaticGraphics.Clear();
  719. continue;
  720. }
  721. // 3D:仅在启用 3D 时清理
  722. if (!is3DEnabled)
  723. continue;
  724. var display3D = item.Value.Child as Cognex.VisionPro3D.Cog3DDisplayV2WF;
  725. if (display3D != null)
  726. {
  727. display3D.Clear();
  728. }
  729. }
  730. catch (System.Windows.Forms.AxHost.InvalidActiveXStateException)
  731. {
  732. // 控件句柄/ActiveX 未就绪时忽略
  733. }
  734. catch (Exception ex)
  735. {
  736. LogHelper.WriteLogError(Lang.切换产品清除主页图像时出错, ex);
  737. }
  738. }
  739. }));
  740. }
  741. }
  742. }