Преглед изворни кода

针对图片保存的优化,当拍照时,还没有获得流程码;将图片缓存,等待SN到位,再存储

844184169 пре 6 месеци
родитељ
комит
599c007d73

+ 4 - 4
TeamAAS-VM/Core/Management.cs

@@ -2320,6 +2320,7 @@ namespace TeamAAS_VP.Core
                                                     if (i == 0)
                                                     {
                                                         _productService.CurrentProductCode = ProductMainSN[i];
+                                                        _eventAggregator.GetEvent<DelaySaveImageNotification>().Publish(true);//通知界面延迟保存图片,等待MES查询结果返回,避免图片和数据不同步
                                                     }
                                                     SendTaskMessage($"产品主sn:{ProductMainSN[i]}", MessageLevel.Info);
                                                 }
@@ -2346,10 +2347,6 @@ namespace TeamAAS_VP.Core
                                         }
                                         else
                                         {
-                                            //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
-                                            await plc.WriteNodeAsync(addressConfig.Out_ScrewFeederIsChanged.Address, (Int16)1); //不发生改变
-                                            await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)2);
-
                                             LogHelper.WriteLogMes($"询问mes失败");
                                             SendTaskMessage($"询问mes失败:{response}", MessageLevel.Error);
 
@@ -2378,6 +2375,7 @@ namespace TeamAAS_VP.Core
                                                 if (i == 0)
                                                 {
                                                     _productService.CurrentProductCode = ProductMainSN[i];
+                                                    _eventAggregator.GetEvent<DelaySaveImageNotification>().Publish(true);//通知界面延迟保存图片,等待MES查询结果返回,避免图片和数据不同步
                                                 }
                                                 SendTaskMessage($"产品主sn:{ProductMainSN[i]}", MessageLevel.Info);
                                             }
@@ -2411,6 +2409,7 @@ namespace TeamAAS_VP.Core
                                         if (i == 0)
                                         {
                                             _productService.CurrentProductCode = ProductMainSN[i];
+                                            _eventAggregator.GetEvent<DelaySaveImageNotification>().Publish(true);//通知界面延迟保存图片,等待MES查询结果返回,避免图片和数据不同步
                                         }
 
                                         LogHelper.WriteLogMes("未启用mes");
@@ -2435,6 +2434,7 @@ namespace TeamAAS_VP.Core
                                     if (i == 0)
                                     {
                                         CTtime = ct;
+                                        _eventAggregator.GetEvent<DelaySaveImageNotification>().Publish(false);//通知界面延迟保存图片,等待MES查询结果返回,避免图片和数据不同步
                                     }
 
                                     //读取产品结果

+ 8 - 0
TeamAAS-VM/Events/DelaySaveImageNotification.cs

@@ -0,0 +1,8 @@
+using Prism.Events;
+
+namespace TeamAAS_VP.Events
+{
+    public class DelaySaveImageNotification : PubSubEvent<bool>
+    {
+    }
+}

+ 89 - 0
TeamAAS-VM/Models/DelaySaveImage.cs

@@ -0,0 +1,89 @@
+using Prism.Mvvm;
+using System.Drawing;
+using TeamAAS_VP.Enums;
+
+namespace TeamAAS_VP.Models
+{
+    /// <summary>
+    /// 延迟保存的图像
+    /// </summary>
+    public class DelaySaveImage : BindableBase
+    {
+        private ProcedureSaveImageModel _SaveImageModel;
+        /// <summary>
+        /// 存图模式
+        /// </summary>
+        public ProcedureSaveImageModel SaveImageModel
+        {
+            get { return _SaveImageModel; }
+            set { SetProperty(ref _SaveImageModel, value); }
+        }
+
+        private ProcedureSaveImagePathModel _SaveImagePathModel;
+        /// <summary>
+        /// 存图路径模式
+        /// </summary>
+        public ProcedureSaveImagePathModel SaveImagePathModel
+        {
+            get { return _SaveImagePathModel; }
+            set { SetProperty(ref _SaveImagePathModel, value); }
+        }
+
+        private string _SavePath;
+        /// <summary>
+        /// 存图路径
+        /// </summary>
+        public string SavePath
+        {
+            get { return _SavePath; }
+            set { SetProperty(ref _SavePath, value); }
+        }
+
+        private Cognex.VisionPro.ICogImage _Image;
+
+        public Cognex.VisionPro.ICogImage Image
+        {
+            get { return _Image; }
+            set { SetProperty(ref _Image, value); }
+        }
+
+        private Bitmap _clonedBitmap;
+        /// <summary>
+        /// 图片克隆,保存图像时使用,避免图像被修改导致保存失败
+        /// </summary>
+        public Bitmap clonedBitmap
+        {
+            get { return _clonedBitmap; }
+            set { SetProperty(ref _clonedBitmap, value); }
+        }
+
+        private bool _result;
+
+        public bool Result
+        {
+            get { return _result; }
+            set { SetProperty(ref _result, value); }
+        }
+
+        private bool _IsCompress;
+        /// <summary>
+        /// 是否压缩图片
+        /// </summary>
+        public bool IsCompress
+        {
+            get { return _IsCompress; }
+            set { SetProperty(ref _IsCompress, value); }
+        }
+
+        //用户定义的图片文件名
+        private string _ImageFileName;
+        /// <summary>
+        /// 用户定义的图片文件名
+        /// </summary>
+        public string ImageFileName
+        {
+            get { return _ImageFileName; }
+            set { SetProperty(ref _ImageFileName, value); }
+        }
+    }
+}

+ 29 - 18
TeamAAS-VM/Models/Product/ProcedureModel.cs

@@ -38,7 +38,7 @@ namespace TeamAAS_VP.Models
         /// <summary>
         /// 触发相机命令
         /// </summary>
-        public string TriggerCommand {  get; set; }
+        public string TriggerCommand { get; set; }
 
         /// <summary>
         /// 机器人
@@ -68,7 +68,7 @@ namespace TeamAAS_VP.Models
         public ObservableCollection<ProcedureOutput> ProcedureOutputs
         {
             get { return _ProcedureOutputs; }
-            set { SetProperty(ref _ProcedureOutputs,value); }
+            set { SetProperty(ref _ProcedureOutputs, value); }
         }
 
         private string _OutputSeparator = ";";
@@ -89,7 +89,7 @@ namespace TeamAAS_VP.Models
         public FeederWorks FeederWorks
         {
             get { return _FeederWorks; }
-            set { SetProperty(ref _FeederWorks,value); }
+            set { SetProperty(ref _FeederWorks, value); }
         }
 
         private FeederStockWorks _FeederStockWorks;
@@ -130,7 +130,7 @@ namespace TeamAAS_VP.Models
         public float ExposureTime
         {
             get { return _ExposureTime; }
-            set { SetProperty(ref _ExposureTime, value);}
+            set { SetProperty(ref _ExposureTime, value); }
         }
 
         private float _Gain;
@@ -151,7 +151,7 @@ namespace TeamAAS_VP.Models
         public CogToolBlock ToolBlock
         {
             get { return _ToolBlock; }
-            set { SetProperty(ref _ToolBlock,value); }
+            set { SetProperty(ref _ToolBlock, value); }
         }
 
         private ObservableCollection<ToolInfo> _ToolInfo = new ObservableCollection<ToolInfo>();
@@ -214,7 +214,7 @@ namespace TeamAAS_VP.Models
             set { SetProperty(ref _OutputPointMode, value); }
         }
 
-        private int _OutputPointCountMax=100;
+        private int _OutputPointCountMax = 100;
         /// <summary>
         /// 每次发送给机器人的点数最大值
         /// </summary>
@@ -229,12 +229,12 @@ namespace TeamAAS_VP.Models
         /// 是否剔除本次识别到的物料与上一次识别到的物料位置过近的点
         /// </summary>
         public bool IsExcludeNearPoint
-            {
+        {
             get { return _IsExcludeNearPoint; }
             set { SetProperty(ref _IsExcludeNearPoint, value); }
         }
 
-        private double _ExcludeNearPointThreshol=1;
+        private double _ExcludeNearPointThreshol = 1;
         /// <summary>
         /// 物料位置过近阈值
         /// </summary>
@@ -305,6 +305,16 @@ namespace TeamAAS_VP.Models
             set { SetProperty(ref _IsCompress, value); }
         }
 
+        private bool _IsDelaySaveImage;
+        /// <summary>
+        /// 是否延迟保存图片
+        /// </summary>
+        public bool IsDelaySaveImage
+        {
+            get { return _IsDelaySaveImage; }
+            set { SetProperty(ref _IsDelaySaveImage, value); }
+        }
+
         private FeederFrequencyModel _FeederFindFrequency;
         /// <summary>
         /// Feeder自动寻频配置
@@ -365,11 +375,11 @@ namespace TeamAAS_VP.Models
         {
             Id = Guid.NewGuid();
             ProcedureOutputs = new ObservableCollection<ProcedureOutput>();
-            ToolInfo= new ObservableCollection<ToolInfo>();
-            FeederFindFrequency= new FeederFrequencyModel();
-            UserDefineParameters= new ObservableCollection<ProcedureUserDefineParam>();
+            ToolInfo = new ObservableCollection<ToolInfo>();
+            FeederFindFrequency = new FeederFrequencyModel();
+            UserDefineParameters = new ObservableCollection<ProcedureUserDefineParam>();
             FeederWorks = new FeederWorks();
-            FeederStockWorks= new FeederStockWorks();
+            FeederStockWorks = new FeederStockWorks();
             LightChannels = new ObservableCollection<ChannelConfig>();
         }
 
@@ -394,9 +404,9 @@ namespace TeamAAS_VP.Models
             {
                 Id = this.Id,
                 Name = this.Name,
-                CameraName=this.CameraName,
+                CameraName = this.CameraName,
                 VisionModel = this.VisionModel,
-                TriggerCommand=this.TriggerCommand,
+                TriggerCommand = this.TriggerCommand,
                 RobotId = this.RobotId,
                 FeederId = this.FeederId,
                 CameraId = this.CameraId,
@@ -419,13 +429,14 @@ namespace TeamAAS_VP.Models
                 SaveImageModel = this.SaveImageModel,
                 SaveImagePathModel = this.SaveImagePathModel,
                 SavePath = this.SavePath,
-                ImageFileNameFormat=this.ImageFileNameFormat,
+                ImageFileNameFormat = this.ImageFileNameFormat,
                 IsCompress = this.IsCompress,
+                IsDelaySaveImage = this.IsDelaySaveImage,
                 FeederFindFrequency = this.FeederFindFrequency?.Copy(),
-                IsExcludeNearPoint=this.IsExcludeNearPoint,
+                IsExcludeNearPoint = this.IsExcludeNearPoint,
                 ExcludeNearPointThreshol = this.ExcludeNearPointThreshol,
-                OutputPointMode=this.OutputPointMode,
-                OutputSeparator=this.OutputSeparator,
+                OutputPointMode = this.OutputPointMode,
+                OutputSeparator = this.OutputSeparator,
                 UserDefineParameters = new ObservableCollection<ProcedureUserDefineParam>(this.UserDefineParameters.Select(udp => udp.Copy())),
                 LightChannels = this.LightChannels == null ? new ObservableCollection<ChannelConfig>() : new ObservableCollection<ChannelConfig>(this.LightChannels.Select(ch => new ChannelConfig
                 {

+ 10 - 0
TeamAAS-VM/Models/ShowRender.cs

@@ -122,6 +122,16 @@ namespace TeamAAS_VP.Models
             set { SetProperty(ref _IsCompress, value); }
         }
 
+        private bool _IsDelaySaveImage;
+        /// <summary>
+        /// 是否延迟保存图片
+        /// </summary>
+        public bool IsDelaySaveImage
+        {
+            get { return _IsDelaySaveImage; }
+            set { SetProperty(ref _IsDelaySaveImage, value); }
+        }
+
         private string _ProceductName;
 
         public string ProceductName

+ 18 - 1
TeamAAS-VM/Resources/Languages/Lang.Designer.cs

@@ -3642,6 +3642,15 @@ namespace TeamAAS_VP.Resources.Languages {
             }
         }
         
+        /// <summary>
+        ///   查找类似 延迟保存图片 的本地化字符串。
+        /// </summary>
+        public static string 延迟保存图片 {
+            get {
+                return ResourceManager.GetString("延迟保存图片", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   查找类似 开启服务器监听 的本地化字符串。
         /// </summary>
@@ -4830,6 +4839,15 @@ namespace TeamAAS_VP.Resources.Languages {
             }
         }
         
+        /// <summary>
+        ///   查找类似 是否延迟保存图片 的本地化字符串。
+        /// </summary>
+        public static string 是否延迟保存图片 {
+            get {
+                return ResourceManager.GetString("是否延迟保存图片", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   查找类似 是否开始测试? 的本地化字符串。
         /// </summary>
@@ -7925,7 +7943,6 @@ namespace TeamAAS_VP.Resources.Languages {
                 return ResourceManager.GetString("角点拖动调整大小", resourceCulture);
             }
         }
-       
         
         /// <summary>
         ///   查找类似 触发命令 的本地化字符串。

+ 44 - 42
TeamAAS-VM/Resources/Languages/Lang.en.resx

@@ -1998,6 +1998,9 @@
   <data name="正在初始化光源控制器" xml:space="preserve">
     <value>Initializing Light Controller</value>
   </data>
+  <data name="通过下相机获取P0" xml:space="preserve">
+    <value>Upper and lower cameras take opposite images, lower camera acquires P0</value>
+  </data>
   <data name="选择下相机视觉流程" xml:space="preserve">
     <value>Select the next camera vision process</value>
   </data>
@@ -2016,6 +2019,9 @@
   <data name="请选择要启用的光源通道" xml:space="preserve">
     <value>Please select a light channel to enable</value>
   </data>
+  <data name="ProcedureSaveImagePathModel_Month_Day_Formula_ProductSN_Time" xml:space="preserve">
+    <value>Year/Month/Day/Recipe Name/Product SN/Product SN + Time</value>
+  </data>
   <data name="固定向上相机1视觉流程ID" xml:space="preserve">
     <value>Fixed Upward Camera 1 Vision Process ID: </value>
   </data>
@@ -2166,9 +2172,26 @@
   <data name="取消校准" xml:space="preserve">
     <value>Cancel Calibration</value>
   </data>
-  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
-  <data name="R补偿" type="System.Resources.ResXNullRef, System.Windows.Forms">
-    <value />
+  <data name="X补偿" xml:space="preserve">
+    <value>X Compensation</value>
+  </data>
+  <data name="Y补偿" xml:space="preserve">
+    <value>Y Compensation</value>
+  </data>
+  <data name="Z起点补偿" xml:space="preserve">
+    <value>Z Start Point Compensation</value>
+  </data>
+  <data name="Z终点补偿" xml:space="preserve">
+    <value>Z End Point Compensation</value>
+  </data>
+  <data name="U补偿" xml:space="preserve">
+    <value>U Compensation</value>
+  </data>
+  <data name="R补偿" xml:space="preserve">
+    <value>R Compensation</value>
+  </data>
+  <data name="清除所有补偿" xml:space="preserve">
+    <value>Clear All Compensation</value>
   </data>
   <data name="取料拍照点位" xml:space="preserve">
     <value>Picking Photo Position</value>
@@ -2296,6 +2319,9 @@
   <data name="B点坐标" xml:space="preserve">
     <value>B Point Coordinates:</value>
   </data>
+  <data name="机器人B点拍照位置坐标" xml:space="preserve">
+    <value>Robot B Point Photo Position Coordinates</value>
+  </data>
   <data name="选择视觉处理流程" xml:space="preserve">
     <value>Select Vision Processing Flow</value>
   </data>
@@ -2422,6 +2448,9 @@
   <data name="极差" xml:space="preserve">
     <value>Range:</value>
   </data>
+  <data name="请填写名称" xml:space="preserve">
+    <value>Please enter the name</value>
+  </data>
   <data name="组装记录查询" xml:space="preserve">
     <value>Assembly Record Query</value>
   </data>
@@ -2659,6 +2688,9 @@
   <data name="是否启用低量报警" xml:space="preserve">
     <value>Enable low quantity alarm:</value>
   </data>
+  <data name="每包螺丝数量:" xml:space="preserve">
+    <value>Screws Per Package:</value>
+  </data>
   <data name="是否移除光源控制器" xml:space="preserve">
     <value>Are you sure to remove the light source controller?</value>
   </data>
@@ -2704,6 +2736,9 @@
   <data name="添加机器人" xml:space="preserve">
     <value>Add Robot</value>
   </data>
+  <data name="添加PLC" xml:space="preserve">
+    <value>Add PLC</value>
+  </data>
   <data name="添加光源控制器" xml:space="preserve">
     <value>Add Light Source Controller</value>
   </data>
@@ -2758,45 +2793,6 @@
   <data name="确认要点动距离0mm吗" xml:space="preserve">
     <value>Confirm jog distance of {0} mm?</value>
   </data>
-  <data name="通过下相机获取P0" xml:space="preserve">
-    <value>Upper and lower cameras take opposite images, lower camera acquires P0</value>
-  </data>
-  <data name="ProcedureSaveImagePathModel_Month_Day_Formula_ProductSN_Time" xml:space="preserve">
-    <value>Year/Month/Day/Recipe Name/Product SN/Product SN + Time</value>
-  </data>
-  <data name="X补偿" xml:space="preserve">
-    <value>X Compensation</value>
-  </data>
-  <data name="Y补偿" xml:space="preserve">
-    <value>Y Compensation</value>
-  </data>
-  <data name="Z起点补偿" xml:space="preserve">
-    <value>Z Start Point Compensation</value>
-  </data>
-  <data name="Z终点补偿" xml:space="preserve">
-    <value>Z End Point Compensation</value>
-  </data>
-  <data name="U补偿" xml:space="preserve">
-    <value>U Compensation</value>
-  </data>
-  <data name="R补偿" xml:space="preserve">
-    <value>R Compensation</value>
-  </data>
-  <data name="清除所有补偿" xml:space="preserve">
-    <value>Clear All Compensation</value>
-  </data>
-  <data name="机器人B点拍照位置坐标" xml:space="preserve">
-    <value>Robot B Point Photo Position Coordinates</value>
-  </data>
-  <data name="请填写名称" xml:space="preserve">
-    <value>Please enter the name</value>
-  </data>
-  <data name="每包螺丝数量:" xml:space="preserve">
-    <value>Screws Per Package:</value>
-  </data>
-  <data name="添加PLC" xml:space="preserve">
-    <value>Add PLC</value>
-  </data>
   <data name="执行点位" xml:space="preserve">
     <value>Execute Point</value>
   </data>
@@ -3118,4 +3114,10 @@
   <data name="没有识别到相机" xml:space="preserve">
     <value>No camera recognized</value>
   </data>
+  <data name="延迟保存图片" xml:space="preserve">
+    <value>Delay saving the image</value>
+  </data>
+  <data name="是否延迟保存图片" xml:space="preserve">
+    <value>Do you want to delay saving the picture</value>
+  </data>
 </root>

+ 45 - 39
TeamAAS-VM/Resources/Languages/Lang.ja-JP.resx

@@ -1998,6 +1998,9 @@
   <data name="正在初始化光源控制器" xml:space="preserve">
     <value>ライトコントローラーを初期化しています</value>
   </data>
+  <data name="通过下相机获取P0" xml:space="preserve">
+    <value>上下カメラ対向撮影、下カメラで P0 を取得</value>
+  </data>
   <data name="选择下相机视觉流程" xml:space="preserve">
     <value>次のカメラビジョンプロセスを選択してください</value>
   </data>
@@ -2016,6 +2019,9 @@
   <data name="请选择要启用的光源通道" xml:space="preserve">
     <value>有効にするライトチャンネルを選択してください</value>
   </data>
+  <data name="ProcedureSaveImagePathModel_Month_Day_Formula_ProductSN_Time" xml:space="preserve">
+    <value>年月 / 日 / レシピ名 / 製品 SN / 製品 SN+時間</value>
+  </data>
   <data name="固定向上相机1视觉流程ID" xml:space="preserve">
     <value>固定アップカメラ 1 ビジョンプロセス ID: </value>
   </data>
@@ -2166,6 +2172,27 @@
   <data name="取消校准" xml:space="preserve">
     <value>キャンセルキャリブレーション</value>
   </data>
+  <data name="X补偿" xml:space="preserve">
+    <value>X 補償</value>
+  </data>
+  <data name="Y补偿" xml:space="preserve">
+    <value>Y 補償</value>
+  </data>
+  <data name="Z起点补偿" xml:space="preserve">
+    <value>Z 起点補償</value>
+  </data>
+  <data name="Z终点补偿" xml:space="preserve">
+    <value>Z 終点補償</value>
+  </data>
+  <data name="U补偿" xml:space="preserve">
+    <value>U 補償</value>
+  </data>
+  <data name="R补偿" xml:space="preserve">
+    <value>R 補償</value>
+  </data>
+  <data name="清除所有补偿" xml:space="preserve">
+    <value>全補償クリア</value>
+  </data>
   <data name="取料拍照点位" xml:space="preserve">
     <value>ピッキング撮影ポジション</value>
   </data>
@@ -2292,6 +2319,9 @@
   <data name="B点坐标" xml:space="preserve">
     <value>B 点座標:</value>
   </data>
+  <data name="机器人B点拍照位置坐标" xml:space="preserve">
+    <value>ロボット B 点撮影位置座標</value>
+  </data>
   <data name="选择视觉处理流程" xml:space="preserve">
     <value>視覚処理フローを選択</value>
   </data>
@@ -2418,6 +2448,9 @@
   <data name="极差" xml:space="preserve">
     <value>範囲:</value>
   </data>
+  <data name="请填写名称" xml:space="preserve">
+    <value>名称を入力してください</value>
+  </data>
   <data name="组装记录查询" xml:space="preserve">
     <value>組立記録照会</value>
   </data>
@@ -2655,6 +2688,9 @@
   <data name="是否启用低量报警" xml:space="preserve">
     <value>低量警報を有効にしますか:</value>
   </data>
+  <data name="每包螺丝数量:" xml:space="preserve">
+    <value>1 袋あたりのネジ本数:</value>
+  </data>
   <data name="是否移除光源控制器" xml:space="preserve">
     <value>光源コントローラーを削除しますか?</value>
   </data>
@@ -2700,6 +2736,9 @@
   <data name="添加机器人" xml:space="preserve">
     <value>ロボットを追加</value>
   </data>
+  <data name="添加PLC" xml:space="preserve">
+    <value>PLC 追加</value>
+  </data>
   <data name="添加光源控制器" xml:space="preserve">
     <value>光源コントローラーを追加</value>
   </data>
@@ -2754,45 +2793,6 @@
   <data name="确认要点动距离0mm吗" xml:space="preserve">
     <value>ジョグ距離 {0} mm を確認しますか?</value>
   </data>
-  <data name="通过下相机获取P0" xml:space="preserve">
-    <value>上下カメラ対向撮影、下カメラで P0 を取得</value>
-  </data>
-  <data name="ProcedureSaveImagePathModel_Month_Day_Formula_ProductSN_Time" xml:space="preserve">
-    <value>年月 / 日 / レシピ名 / 製品 SN / 製品 SN+時間</value>
-  </data>
-  <data name="X补偿" xml:space="preserve">
-    <value>X 補償</value>
-  </data>
-  <data name="Y补偿" xml:space="preserve">
-    <value>Y 補償</value>
-  </data>
-  <data name="Z起点补偿" xml:space="preserve">
-    <value>Z 起点補償</value>
-  </data>
-  <data name="Z终点补偿" xml:space="preserve">
-    <value>Z 終点補償</value>
-  </data>
-  <data name="U补偿" xml:space="preserve">
-    <value>U 補償</value>
-  </data>
-  <data name="R补偿" xml:space="preserve">
-    <value>R 補償</value>
-  </data>
-  <data name="清除所有补偿" xml:space="preserve">
-    <value>全補償クリア</value>
-  </data>
-  <data name="机器人B点拍照位置坐标" xml:space="preserve">
-    <value>ロボット B 点撮影位置座標</value>
-  </data>
-  <data name="请填写名称" xml:space="preserve">
-    <value>名称を入力してください</value>
-  </data>
-  <data name="每包螺丝数量:" xml:space="preserve">
-    <value>1 袋あたりのネジ本数:</value>
-  </data>
-  <data name="添加PLC" xml:space="preserve">
-    <value>PLC 追加</value>
-  </data>
   <data name="执行点位" xml:space="preserve">
     <value>実行ポイント</value>
   </data>
@@ -3114,4 +3114,10 @@
   <data name="没有识别到相机" xml:space="preserve">
     <value>カメラが認識されません</value>
   </data>
+  <data name="延迟保存图片" xml:space="preserve">
+    <value>画像の保存を遅延</value>
+  </data>
+  <data name="是否延迟保存图片" xml:space="preserve">
+    <value>画像の保存を遅延しますか?</value>
+  </data>
 </root>

+ 8 - 0
TeamAAS-VM/Resources/Languages/Lang.resx

@@ -3226,4 +3226,12 @@
   <data name="没有识别到相机" xml:space="preserve">
     <value>没有识别到相机</value>
   </data>
+  <data name="延迟保存图片" xml:space="preserve">
+    <value>延迟保存图片</value>
+    <comment>延迟保存图片</comment>
+  </data>
+  <data name="是否延迟保存图片" xml:space="preserve">
+    <value>是否延迟保存图片</value>
+    <comment>是否延迟保存图片</comment>
+  </data>
 </root>

+ 45 - 39
TeamAAS-VM/Resources/Languages/Lang.zh-TW.resx

@@ -1998,6 +1998,9 @@
   <data name="正在初始化光源控制器" xml:space="preserve">
     <value>正在初始化光源控制器</value>
   </data>
+  <data name="通过下相机获取P0" xml:space="preserve">
+    <value>上下相機對拍,下相機取得 P0</value>
+  </data>
   <data name="选择下相机视觉流程" xml:space="preserve">
     <value>選擇下相機視覺流程</value>
   </data>
@@ -2016,6 +2019,9 @@
   <data name="请选择要启用的光源通道" xml:space="preserve">
     <value>請選擇要啟用的光源通道</value>
   </data>
+  <data name="ProcedureSaveImagePathModel_Month_Day_Formula_ProductSN_Time" xml:space="preserve">
+    <value>年月 / 日 / 配方名 / 產品 SN / 產品 SN + 時間</value>
+  </data>
   <data name="固定向上相机1视觉流程ID" xml:space="preserve">
     <value>固定向上相機 1 視覺流程 ID: </value>
   </data>
@@ -2166,6 +2172,27 @@
   <data name="取消校准" xml:space="preserve">
     <value>取消校準</value>
   </data>
+  <data name="X补偿" xml:space="preserve">
+    <value>X 補償</value>
+  </data>
+  <data name="Y补偿" xml:space="preserve">
+    <value>Y 補償</value>
+  </data>
+  <data name="Z起点补偿" xml:space="preserve">
+    <value>Z 起點補償</value>
+  </data>
+  <data name="Z终点补偿" xml:space="preserve">
+    <value>Z 終點補償</value>
+  </data>
+  <data name="U补偿" xml:space="preserve">
+    <value>U 補償</value>
+  </data>
+  <data name="R补偿" xml:space="preserve">
+    <value>R 補償</value>
+  </data>
+  <data name="清除所有补偿" xml:space="preserve">
+    <value>清除所有補償</value>
+  </data>
   <data name="取料拍照点位" xml:space="preserve">
     <value>取料拍照點位</value>
   </data>
@@ -2292,6 +2319,9 @@
   <data name="B点坐标" xml:space="preserve">
     <value>B 點座標:</value>
   </data>
+  <data name="机器人B点拍照位置坐标" xml:space="preserve">
+    <value>機器人 B 點拍照位置座標</value>
+  </data>
   <data name="选择视觉处理流程" xml:space="preserve">
     <value>選擇視覺處理流程</value>
   </data>
@@ -2418,6 +2448,9 @@
   <data name="极差" xml:space="preserve">
     <value>極差:</value>
   </data>
+  <data name="请填写名称" xml:space="preserve">
+    <value>請填寫名稱</value>
+  </data>
   <data name="组装记录查询" xml:space="preserve">
     <value>組裝記錄查詢</value>
   </data>
@@ -2655,6 +2688,9 @@
   <data name="是否启用低量报警" xml:space="preserve">
     <value>是否啟用低量警報:</value>
   </data>
+  <data name="每包螺丝数量:" xml:space="preserve">
+    <value>每包螺絲數量:</value>
+  </data>
   <data name="是否移除光源控制器" xml:space="preserve">
     <value>是否移除光源控制器?</value>
   </data>
@@ -2700,6 +2736,9 @@
   <data name="添加机器人" xml:space="preserve">
     <value>新增機器人</value>
   </data>
+  <data name="添加PLC" xml:space="preserve">
+    <value>新增 PLC</value>
+  </data>
   <data name="添加光源控制器" xml:space="preserve">
     <value>新增光源控制器</value>
   </data>
@@ -2754,45 +2793,6 @@
   <data name="确认要点动距离0mm吗" xml:space="preserve">
     <value>確認要點動距離 {0} mm 嗎?</value>
   </data>
-  <data name="通过下相机获取P0" xml:space="preserve">
-    <value>上下相機對拍,下相機取得 P0</value>
-  </data>
-  <data name="ProcedureSaveImagePathModel_Month_Day_Formula_ProductSN_Time" xml:space="preserve">
-    <value>年月 / 日 / 配方名 / 產品 SN / 產品 SN + 時間</value>
-  </data>
-  <data name="X补偿" xml:space="preserve">
-    <value>X 補償</value>
-  </data>
-  <data name="Y补偿" xml:space="preserve">
-    <value>Y 補償</value>
-  </data>
-  <data name="Z起点补偿" xml:space="preserve">
-    <value>Z 起點補償</value>
-  </data>
-  <data name="Z终点补偿" xml:space="preserve">
-    <value>Z 終點補償</value>
-  </data>
-  <data name="U补偿" xml:space="preserve">
-    <value>U 補償</value>
-  </data>
-  <data name="R补偿" xml:space="preserve">
-    <value>R 補償</value>
-  </data>
-  <data name="清除所有补偿" xml:space="preserve">
-    <value>清除所有補償</value>
-  </data>
-  <data name="机器人B点拍照位置坐标" xml:space="preserve">
-    <value>機器人 B 點拍照位置座標</value>
-  </data>
-  <data name="请填写名称" xml:space="preserve">
-    <value>請填寫名稱</value>
-  </data>
-  <data name="每包螺丝数量:" xml:space="preserve">
-    <value>每包螺絲數量:</value>
-  </data>
-  <data name="添加PLC" xml:space="preserve">
-    <value>新增 PLC</value>
-  </data>
   <data name="执行点位" xml:space="preserve">
     <value>執行點位</value>
   </data>
@@ -3114,4 +3114,10 @@
   <data name="没有识别到相机" xml:space="preserve">
     <value>沒有識別到相機</value>
   </data>
+  <data name="延迟保存图片" xml:space="preserve">
+    <value>延遲保存圖片</value>
+  </data>
+  <data name="是否延迟保存图片" xml:space="preserve">
+    <value>是否延遲保存圖片</value>
+  </data>
 </root>

+ 3 - 0
TeamAAS-VM/Services/RemoteCommandService.cs

@@ -1549,6 +1549,7 @@ namespace TeamAAS_VP.Services
                         SaveImagePathModel = procedure.SaveImagePathModel,
                         SavePath = procedure.SavePath,
                         IsCompress = procedure.IsCompress,
+                        IsDelaySaveImage = procedure.IsDelaySaveImage,
                         ProceductName = procedure.Name,
                         ImageFileName = imgName
                     });
@@ -1588,6 +1589,8 @@ namespace TeamAAS_VP.Services
                         SaveImageModel = procedure.SaveImageModel,
                         SaveImagePathModel = procedure.SaveImagePathModel,
                         SavePath = procedure.SavePath,
+                        IsCompress = procedure.IsCompress,
+                        IsDelaySaveImage = procedure.IsDelaySaveImage,
                         ProceductName = procedure.Name,
                         ImageFileName = imgName
                     });

+ 2 - 0
TeamAAS-VM/TeamAAS-VP.csproj

@@ -536,11 +536,13 @@
     <Compile Include="Core\RectangleCenterCalculator.cs" />
     <Compile Include="Core\StabilityAnalyzer.cs" />
     <Compile Include="Core\VisionProFileHelper.cs" />
+    <Compile Include="Events\DelaySaveImageNotification.cs" />
     <Compile Include="Events\MainTabSwitchNotification.cs" />
     <Compile Include="Interfaces\IMesService.cs" />
     <Compile Include="Models\AssemblyRecord.cs" />
     <Compile Include="Models\CTQ_Data.cs" />
     <Compile Include="Models\DataFormCtq.cs" />
+    <Compile Include="Models\DelaySaveImage.cs" />
     <Compile Include="Models\DeviceInfo.cs" />
     <Compile Include="Models\Feeder\ScrewFeederInfo.cs" />
     <Compile Include="Models\PhotoCaptureRecord.cs" />

+ 70 - 12
TeamAAS-VM/Views/Home/ShowVisionRender.xaml.cs

@@ -36,6 +36,8 @@ namespace TeamAAS_VP.Views.Home
         private readonly ISystemDatabaseService _systemDatabaseService;
         private readonly IProductService _productService;
 
+        private List<DelaySaveImage> delaySaveImages = new List<DelaySaveImage>();
+
         // ======================= 【新增】保存任务控制:防闪退/防资源泄露 =======================
         private CancellationTokenSource _saveImageCts = new CancellationTokenSource();
         private readonly SemaphoreSlim _saveSemaphore = new SemaphoreSlim(2, 2);
@@ -56,6 +58,7 @@ namespace TeamAAS_VP.Views.Home
             viewModel.UpdateLayout += ViewModel_UpdateLayout;
             _eventAggregator.GetEvent<RenderUpdateNotification>().Subscribe(UpdateRenderModuleSource);
             _eventAggregator.GetEvent<ProductChangedNotification>().Subscribe(ProductChanged);
+            _eventAggregator.GetEvent<DelaySaveImageNotification>().Subscribe(UpdateDelaySaveImage);
 
             // 【可选】控件卸载时取消所有保存任务,避免页面关闭后仍在截图/保存导致闪退
             this.Unloaded += ShowVisionRender_Unloaded;
@@ -308,16 +311,35 @@ namespace TeamAAS_VP.Views.Home
                         {
                             token.ThrowIfCancellationRequested();
 
-                            SaveImage(
-                                render.SaveImageModel,
-                                render.SaveImagePathModel,
-                                render.SavePath,
-                                render.Image,
-                                clonedBitmap,
-                                render.Result,
-                                render.IsCompress,
-                                render.ImageFileName
-                            );
+                            if (render.IsDelaySaveImage)// 延迟保存(适合你那边后续有处理的场景)
+                            {
+                                // 创建延迟保存项,转移资源所有权
+                                var delayItem = new DelaySaveImage()
+                                {
+                                    SaveImageModel = render.SaveImageModel,
+                                    SaveImagePathModel = render.SaveImagePathModel,
+                                    SavePath = render.SavePath,
+                                    Image = render.Image?.CopyBase(CogImageCopyModeConstants.CopyPixels), // 深拷贝ICogImage
+                                    clonedBitmap = (Bitmap)clonedBitmap.Clone(),      // 转移所有权
+                                    Result = render.Result,
+                                    IsCompress = render.IsCompress,
+                                    ImageFileName = render.ImageFileName
+                                };
+                                delaySaveImages.Add(delayItem);
+                            }
+                            else
+                            {
+                                SaveImage(
+                                    render.SaveImageModel,
+                                    render.SaveImagePathModel,
+                                    render.SavePath,
+                                    render.Image,
+                                    clonedBitmap,
+                                    render.Result,
+                                    render.IsCompress,
+                                    render.ImageFileName
+                                );
+                            }
                         }
                         catch (OperationCanceledException)
                         {
@@ -347,6 +369,43 @@ namespace TeamAAS_VP.Views.Home
             }));
         }
 
+        private void UpdateDelaySaveImage(bool isSave)
+        {
+            if (!isSave)
+            {
+                delaySaveImages.Clear();
+                return;
+            }
+
+            // 这里简单遍历保存,实际可以根据需要优化(如批量处理/分队列等)
+            foreach (var item in delaySaveImages)
+            {
+                try
+                {
+                    SaveImage(
+                        item.SaveImageModel,
+                        item.SaveImagePathModel,
+                        item.SavePath,
+                        item.Image,
+                        item.clonedBitmap,
+                        item.Result,
+                        item.IsCompress,
+                        item.ImageFileName
+                    );
+                }
+                catch (Exception ex)
+                {
+                    LogHelper.WriteLogError("UpdateDelaySaveImage 保存图像时出错!", ex);
+                }
+                finally
+                {
+                    // 保存后���放资源
+                    try { item.clonedBitmap?.Dispose(); } catch { }
+                }
+            }
+            delaySaveImages.Clear();
+        }
+
         /// <summary>
         /// 保存图像(保持你原有逻辑不变,补充 Dispose 兜底,防止压缩分支不释放导致闪退)
         /// </summary>
@@ -520,11 +579,10 @@ namespace TeamAAS_VP.Views.Home
                                 formulaName = formulaName.Replace(c, '_');
 
                             string productSN = _productService.CurrentProductCode;
-                            if(productSN!=null)
+                            if (!string.IsNullOrEmpty(productSN))
                             {
                                 foreach (char c in Path.GetInvalidFileNameChars())
                                     productSN = productSN.Replace(c, '_');
-
                             }
 
                             string resultStr = result ? "OK" : "NG";

+ 17 - 6
TeamAAS-VM/Views/Product/ProcedureParams.xaml

@@ -431,19 +431,30 @@
                               Visibility="{Binding ElementName=chbSaveImage,Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}"
                               IsChecked="{Binding SelectProcedure.IsCompress,Mode=TwoWay}"
                               Style="{StaticResource MaterialDesignLightCheckBox}" />
-                    <!--图片名称格式-->
+                    <!--是否延迟保存图片-->
                     <TextBlock Grid.Row="14"
+                               Grid.Column="0"
+                               Visibility="{Binding ElementName=chbSaveImage,Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}"
+                               Text="{lex:Loc 延迟保存图片,Converter={StaticResource StringFormatConverter},ConverterParameter='{}{0}: '}" />
+                    <CheckBox Grid.Row="14"
+                              Grid.Column="1"
+                              Content="{lex:Loc 是否延迟保存图片}"
+                              Visibility="{Binding ElementName=chbSaveImage,Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}"
+                              IsChecked="{Binding SelectProcedure.IsDelaySaveImage,Mode=TwoWay}"
+                              Style="{StaticResource MaterialDesignLightCheckBox}" />
+                    <!--图片名称格式-->
+                    <TextBlock Grid.Row="15"
                                Grid.Column="0"
                                Visibility="{Binding ElementName=chbSaveImage,Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}"
                                Text="图片名称格式:" />
-                    <TextBox Grid.Row="14"
+                    <TextBox Grid.Row="15"
                              Grid.Column="1"
                              HorizontalAlignment="Stretch"
                              Visibility="{Binding ElementName=chbSaveImage,Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}"
                              Text="{Binding SelectProcedure.ImageFileNameFormat,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
                     </TextBox>
                     <!--示例-->
-                    <StackPanel Grid.Row="15"
+                    <StackPanel Grid.Row="16"
                                 Grid.Column="0"
                                 Grid.ColumnSpan="2"
                                 Orientation="Vertical"
@@ -466,7 +477,7 @@
                     </StackPanel>
 
                     <!--自定义参数-->
-                    <GroupBox Grid.Row="16"
+                    <GroupBox Grid.Row="17"
                               Grid.Column="0"
                               Grid.ColumnSpan="2"
                               HorizontalAlignment="Stretch"
@@ -536,10 +547,10 @@
                             </DataGrid>
                         </DockPanel>
                     </GroupBox>
-                    <TextBlock Grid.Row="17"
+                    <TextBlock Grid.Row="18"
                                Grid.Column="0"
                                Text="{lex:Loc 重写视觉处理逻辑}" />
-                    <Button Grid.Row="17"
+                    <Button Grid.Row="18"
                             Grid.Column="1"
                             Margin="0,2,0,0"
                             Command="{Binding OverrideVisionTaskCommand}">