ShowVisionRender.xaml.cs 38 KB

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