From 6bb231b53dcb5e21585d54e26ec872e3026fc8fb Mon Sep 17 00:00:00 2001
From: C3032 <C3032@test001.com>
Date: 星期五, 19 十二月 2025 15:14:40 +0800
Subject: [PATCH] 更新HR相机模块代码

---
 LB_SmartVision/Forms/Pages/CameraPage/CreateCameraForm.cs |    4 
 LB_VisionProcesses/Cameras/HRCamera.cs                    |  920 ++++++++++++++++++++++++++++++++++
 LB_SmartVision/ProcessRun/ProcessContext.cs               |   12 
 LB_VisionProcesses/Cameras/2DCameraForm.Designer.cs       |  273 ++++++----
 LB_VisionFlowNode/IFlowContext.cs                         |  363 ------------
 LB_VisionProcesses/Cameras/2DCameraForm.cs                |   13 
 6 files changed, 1,127 insertions(+), 458 deletions(-)

diff --git a/LB_SmartVision/Forms/Pages/CameraPage/CreateCameraForm.cs b/LB_SmartVision/Forms/Pages/CameraPage/CreateCameraForm.cs
index 1a9d3a5..26e09ee 100644
--- a/LB_SmartVision/Forms/Pages/CameraPage/CreateCameraForm.cs
+++ b/LB_SmartVision/Forms/Pages/CameraPage/CreateCameraForm.cs
@@ -27,7 +27,7 @@
             // 绂佹淇敼绐楀彛澶у皬
             this.FormBorderStyle = FormBorderStyle.FixedDialog;
             if (camera == null)
-                //camera = new HRCamera();
+                camera = new HRCamera();
 
             uiButtonCreate.Enabled = false;
         }
@@ -96,7 +96,7 @@
             switch (brand)
             {
                 case CameraBrand.HRCamera:
-                    //camera = new HRCamera();
+                    camera = new HRCamera();
                     break;
                 case CameraBrand.LBCamera:
                     //camera = new LBCamera();
diff --git a/LB_SmartVision/ProcessRun/ProcessContext.cs b/LB_SmartVision/ProcessRun/ProcessContext.cs
index 5fabc0c..a50eb67 100644
--- a/LB_SmartVision/ProcessRun/ProcessContext.cs
+++ b/LB_SmartVision/ProcessRun/ProcessContext.cs
@@ -533,6 +533,18 @@
             }
         }
 
+
+        #region 娉ㄥ唽宸ュ叿浜嬩欢
+
+        [Node("鐩告満鍙栧浘", "鍙栧儚宸ュ叿", "Basic", "鐩告満鍙栧浘")]
+        public void 鐩告満鍙栧浘(FlowNode node) { RunNodeAsync(node); }
+
+        #endregion
+
+
+
+
+
         [Node("寮�濮�", "鎺у埗", "Logic", "寮�濮�")]
         public override void 寮�濮�(FlowNode node)
         {
diff --git a/LB_VisionFlowNode/IFlowContext.cs b/LB_VisionFlowNode/IFlowContext.cs
index 4ca3882..e0b7147 100644
--- a/LB_VisionFlowNode/IFlowContext.cs
+++ b/LB_VisionFlowNode/IFlowContext.cs
@@ -1,6 +1,7 @@
 锘縰sing LB_VisionProcesses;
 using System;
 using System.Diagnostics;
+using System.Linq;
 using System.Reflection;
 using System.Reflection.Emit;
 using System.Text.Json.Nodes;
@@ -20,7 +21,7 @@
         public string Group { get; set; }
         public string Description { get; set; }
     }
-    public abstract class IFlowContext
+    public class IFlowContext
     {
         public readonly Dictionary<string, MethodInfo> _nodeMethods
             = new Dictionary<string, MethodInfo>();
@@ -31,33 +32,10 @@
         public readonly Dictionary<string, Func<FlowNode, bool>> _nodeDelegates
             = new Dictionary<string, Func<FlowNode, bool>>();
 
-        // 鑷姩鐢熸垚鐨勬彃浠惰妭鐐规柟娉曚俊鎭�
-        public readonly Dictionary<string, PluginNodeMethodInfo> _pluginNodeMethods
-            = new Dictionary<string, PluginNodeMethodInfo>();
-
-        // 鍔ㄦ�佹柟娉曠殑鍖呰锛堢敤浜庢ā鎷烳ethodInfo锛�
-        private readonly Dictionary<string, DynamicMethodWrapper> _dynamicMethodWrappers
-            = new Dictionary<string, DynamicMethodWrapper>();
-
-        // 鏄惁宸茶嚜鍔ㄧ敓鎴愭彃浠惰妭鐐�
-        private bool _pluginNodesGenerated = false;
-
-        // 鍔ㄦ�佹柟娉曞寘瑁呯被
-        public class DynamicMethodWrapper
-        {
-            public string DisplayName { get; set; }
-            public string Category { get; set; }
-            public string Group { get; set; }
-            public string Description { get; set; }
-            public Func<FlowNode, bool> Execute { get; set; }
-            // 妯℃嫙MethodInfo鐨勫繀瑕佸睘鎬�
-            public string Name => DisplayName;
-        }
-
         public void InitializeMethods()
         {
-            // 1. 鍏堝鐞嗚嚜韬殑Node鐗规�ф柟娉�
             var methods = GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance);
+
             foreach (var method in methods)
             {
                 var nodeAttr = method.GetCustomAttribute<NodeAttribute>();
@@ -74,269 +52,28 @@
                     _groupedMethods[nodeAttr.Group].Add(method);
                 }
             }
-
-            // 2. 鑷姩涓篒Process宸ュ叿鐢熸垚鍔ㄦ�佽妭鐐规柟娉�
-            GeneratePluginNodeMethods();
-        }
-
-        /// <summary>
-        /// 鑷姩涓篒Process宸ュ叿鐢熸垚鑺傜偣鏂规硶锛堟牳蹇冩柟娉曪級
-        /// </summary>
-        private void GeneratePluginNodeMethods()
-        {
-            if (_pluginNodesGenerated)
-                return;
-            try
-            {
-                // 纭繚IProcess鐨勬彃浠剁鐞嗗櫒宸插垵濮嬪寲
-                if (IProcess.dicProcesses == null || IProcess.dicProcesses.Count == 0)
-                {
-                    var _ = IProcess.dicProcesses; // 瑙﹀彂鍒濆鍖�
-                }
-                // 娓呯┖鐜版湁鐨勬彃浠惰妭鐐规柟娉�
-                _pluginNodeMethods.Clear();
-                _dynamicMethodWrappers.Clear();
-                // 閬嶅巻鎵�鏈塈Process宸ュ叿
-                foreach (var processKvp in IProcess.dicProcesses)
-                {
-                    string toolName = processKvp.Key;
-                    string className = processKvp.Value;
-                    // 鑾峰彇宸ュ叿鐨勫垎绫�
-                    string category = GetCategoryForTool(toolName);
-                    string group = GetGroupForCategory(category); // 鏍规嵁鍒嗙被纭畾缁�
-                    string description = $"{toolName}";
-
-                    // 鍒涘缓鎻掍欢鑺傜偣鏂规硶淇℃伅
-                    var pluginNode = new PluginNodeMethodInfo
-                    {
-                        DisplayName = toolName,
-                        FullTypeName = className,
-                        Category = category,
-                        Group = group,
-                        Description = description
-                    };
-                    _pluginNodeMethods[toolName] = pluginNode;
-
-                    // 鍒涘缓鍔ㄦ�佹墽琛屽鎵�
-                    Func<FlowNode, bool> executeDelegate = (node) =>
-                    {
-                        try
-                        {
-                            // 鍒涘缓IProcess瀹炰緥
-                            IProcess process = IProcess.CreateProcess(toolName);
-                            if (process == null)
-                            {
-                                Debug.WriteLine($"鏃犳硶鍒涘缓宸ュ叿瀹炰緥: {toolName}");
-                                node.Result = false;
-                                return false;
-                            }
-
-                            // 鍒濆鍖栬繍琛屽弬鏁�
-                            process.InitRunParams();
-
-                            // 鎵ц宸ュ叿鐨凴un鏂规硶
-                            bool runResult = process.Run();
-
-                            // 璁剧疆鑺傜偣缁撴灉
-                            node.Result = runResult;
-                            node.BranchIndex = "0"; // 榛樿鍒嗘敮
-
-                            // 閲婃斁璧勬簮
-                            process.Dispose();
-
-                            Debug.WriteLine($"鎻掍欢宸ュ叿 {toolName} 鎵ц瀹屾垚锛岀粨鏋�: {runResult}");
-                            return runResult;
-                        }
-                        catch (Exception ex)
-                        {
-                            Debug.WriteLine($"鎻掍欢宸ュ叿 {toolName} 鎵ц澶辫触: {ex.Message}");
-                            node.Result = false;
-                            return false;
-                        }
-                    };
-
-                    // 鍒涘缓鍔ㄦ�佹柟娉曞寘瑁�
-                    var dynamicMethod = new DynamicMethodWrapper
-                    {
-                        DisplayName = toolName,
-                        Category = category,
-                        Group = group,
-                        Description = description,
-                        Execute = executeDelegate
-                    };
-                    _dynamicMethodWrappers[description] = dynamicMethod;
-
-                    // ********** 鍏抽敭锛氬皢鍔ㄦ�佹柟娉曟坊鍔犲埌_nodeMethods鍜宊groupedMethods **********
-                    // 鏂瑰紡锛氱敓鎴愬姩鎬丮ethodInfo锛堜娇鐢‥mit锛夛紝鎴栬�呮ā鎷燂紙杩欓噷鐢‥mit鐢熸垚鐪熷疄鐨凪ethodInfo锛�
-                    MethodInfo dynamicMethodInfo = CreateDynamicMethod(toolName, group, description);
-
-                    // 娣诲姞鍒癬nodeMethods锛堥敭鏄痙escription锛�
-                    _nodeMethods[description] = dynamicMethodInfo;
-
-                    // 娣诲姞鍒癬groupedMethods
-                    if (!_groupedMethods.ContainsKey(group))
-                    {
-                        _groupedMethods[group] = new List<MethodInfo>();
-                    }
-                    _groupedMethods[group].Add(dynamicMethodInfo);
-
-                    // 娣诲姞鍒癬nodeDelegates
-                    _nodeDelegates[description] = executeDelegate;
-
-                    Debug.WriteLine($"鑷姩鐢熸垚鎻掍欢鑺傜偣: {toolName} (鍒嗙被: {category}, 缁�: {group})");
-                }
-
-                _pluginNodesGenerated = true;
-            }
-            catch (Exception ex)
-            {
-                Debug.WriteLine($"鑷姩鐢熸垚鎻掍欢鑺傜偣鏂规硶澶辫触: {ex.Message}");
-            }
-        }
-
-        /// <summary>
-        /// 浣跨敤Reflection.Emit鐢熸垚鍔ㄦ�丮ethodInfo锛屾ā鎷烴ode鐗规�ф柟娉�
-        /// </summary>
-        /// <param name="toolName">宸ュ叿鍚嶇О</param>
-        /// <param name="group">缁勫悕</param>
-        /// <param name="description">鎻忚堪</param>
-        /// <returns>鍔ㄦ�佺敓鎴愮殑MethodInfo</returns>
-        private MethodInfo CreateDynamicMethod(string toolName, string group, string description)
-        {
-            // 1. 瀹氫箟鍔ㄦ�佹柟娉曠殑鍙傛暟鍜岃繑鍥炵被鍨�
-            Type flowNodeType = typeof(FlowNode);
-            DynamicMethod dynamicMethod = new DynamicMethod(
-                toolName,                  // 鏂规硶鍚�
-                typeof(void),               // 杩斿洖绫诲瀷锛堝拰鍘熸湁Node鏂规硶涓�鑷达級
-                new[] { typeof(FlowNode) }, // 鍙傛暟绫诲瀷
-                GetType(),                  // 鎵�灞炵被鍨�
-                true);                      // 璺宠繃JIT鍙鎬ф鏌�
-
-            // 2. 鐢熸垚IL浠g爜锛岃皟鐢ㄥ姩鎬佸鎵�
-            ILGenerator il = dynamicMethod.GetILGenerator();
-            // 鍔犺浇鍙傛暟锛團lowNode锛�
-            il.Emit(OpCodes.Ldarg_1); // 娉ㄦ剰锛氬疄渚嬫柟娉曠殑绗竴涓弬鏁版槸this锛圠darg_0锛夛紝杩欓噷鍔ㄦ�佹柟娉曟槸闈欐�佺殑锛屾墍浠darg_0鏄疐lowNode
-                                      // 璋冪敤濮旀墭锛堣繖閲岀畝鍖栵紝鐩存帴璁剧疆Result涓簍rue锛�
-            il.Emit(OpCodes.Ldflda, flowNodeType.GetProperty("Result").GetSetMethod());
-            il.Emit(OpCodes.Ldc_I4_1);
-            il.Emit(OpCodes.Callvirt, flowNodeType.GetProperty("Result").GetSetMethod());
-            // 璁剧疆BranchIndex
-            il.Emit(OpCodes.Ldarg_1);
-            il.Emit(OpCodes.Ldflda, flowNodeType.GetProperty("BranchIndex").GetSetMethod());
-            il.Emit(OpCodes.Ldstr, "0");
-            il.Emit(OpCodes.Callvirt, flowNodeType.GetProperty("BranchIndex").GetSetMethod());
-            // 杩斿洖
-            il.Emit(OpCodes.Ret);
-
-            // 3. 灏咲ynamicMethod鍖呰涓篗ethodInfo锛圖ynamicMethod缁ф壙鑷狹ethodInfo锛�
-            return dynamicMethod;
-        }
-
-        /// <summary>
-        /// 鏍规嵁宸ュ叿鍚嶇О鎺ㄦ柇鍒嗙被锛堝畬鍠勯�昏緫锛�
-        /// </summary>
-        private string GetCategoryForTool(string toolName)
-        {
-            if (string.IsNullOrWhiteSpace(toolName))
-                return "鏈垎绫�";
-
-            toolName = toolName.ToLower();
-
-            if (toolName.Contains("鐩告満") || toolName.Contains("鍙栧浘"))
-                return "鐩告満宸ュ叿";
-            else if (toolName.Contains("閫氳") || toolName.Contains("command"))
-                return "閫氳宸ュ叿";
-            else if (toolName.Contains("opencvsharp"))
-                return "OpencvSharp绠楁硶";
-            else if (toolName.Contains("halcon"))
-                return "Halcon绠楁硶";
-            else if (toolName.Contains("yolo") || toolName.Contains("tensorrt") ||
-                     toolName.Contains("ocr") || toolName.Contains("deeplearning") || toolName.Contains("澶фā鍨�"))
-                return "娣卞害瀛︿範";
-            else if (toolName.Contains("鍥惧儚澶勭悊") || toolName.Contains("鐐逛簯") ||
-                     toolName.Contains("绾跨嚎浜ょ偣"))
-                return "鍥惧儚澶勭悊宸ュ叿";
-            else if (toolName.Contains("娴嬭瘯") || toolName.Contains("妫�鏌�") ||
-                     toolName.Contains("绔彛") || toolName.Contains("灞忓箷") ||
-                     toolName.Contains("宸ュ簭") || toolName.Contains("杞骇"))
-                return "鑷畾涔夊伐鍏�";
-            else if (toolName.Contains("鑴氭湰") || toolName.Contains("鍒嗘敮") ||
-                     toolName.Contains("寤舵椂") || toolName.Contains("缁樺埗"))
-                return "宸ュ叿";
-            else if (toolName.Contains("鍥哄畾璺熼殢") || toolName.Contains("fixture"))
-                return "宸ュ叿";
-            else
-                return "鎻掍欢宸ュ叿";
-        }
-
-        /// <summary>
-        /// 鏍规嵁鍒嗙被纭畾缁勫悕
-        /// </summary>
-        private string GetGroupForCategory(string category)
-        {
-            switch (category)
-            {
-                case "閫氳宸ュ叿":
-                    return "Basic";
-                case "绠楁硶":
-                    return "Basic";
-                case "娣卞害瀛︿範":
-                    return "Basic";
-                case "鍥惧儚澶勭悊宸ュ叿":
-                    return "Basic";
-                case "鑷畾涔夊伐鍏�":
-                    return "Basic";
-                case "宸ュ叿":
-                    return "Basic";
-                default:
-                    return "Plugin";
-            }
         }
 
         public void InitializeDelegates()
         {
-            // 1. 澶勭悊鑷韩鐨凬ode鏂规硶
             foreach (var kvp in _nodeMethods)
             {
                 var method = kvp.Value;
                 var parameters = method.GetParameters();
 
-                //濡傛灉鏄姩鎬佹柟娉曪紙DynamicMethod锛夛紝璺宠繃锛堝凡缁忓湪GeneratePluginNodeMethods涓坊鍔犱簡濮旀墭锛�
-                if (method is DynamicMethod)
-                {
-                    // 浠庡姩鎬佹柟娉曞寘瑁呬腑鑾峰彇瀵瑰簲鐨勫鎵�
-                    if (_dynamicMethodWrappers.TryGetValue(kvp.Key, out var wrapper))
-                    {
-                        // 鐩存帴浣跨敤鍖呰涓殑Execute濮旀墭
-                        _nodeDelegates[kvp.Key] = wrapper.Execute;
-                    }
-                    else
-                    {
-                        // 濡傛灉娌℃湁鎵惧埌鍖呰锛屽垱寤轰竴涓粯璁ょ殑鎵ц濮旀墭
-                        _nodeDelegates[kvp.Key] = (node) =>
-                        {
-                            Debug.WriteLine($"鎵ц鍔ㄦ�佹柟娉�: {kvp.Key}");
-                            node.Result = true;
-                            node.BranchIndex = "0";
-                            return true;
-                        };
-                    }
-                    continue;
-                }
-
                 if (parameters.Length == 0)
                 {
+                    // 鏃犲弬鏁版柟娉�
                     var action = (Action)Delegate.CreateDelegate(typeof(Action), this, method);
                     _nodeDelegates[kvp.Key] = (node) => { action(); return node.Result; };
                 }
                 else if (parameters.Length == 1 && parameters[0].ParameterType == typeof(FlowNode))
                 {
+                    // 甯lowNode鍙傛暟鐨勬柟娉�
                     var action = (Action<FlowNode>)Delegate.CreateDelegate(typeof(Action<FlowNode>), this, method);
                     _nodeDelegates[kvp.Key] = (node) => { action(node); return node.Result; };
                 }
             }
-
-            // 2. 纭繚鍔ㄦ�佹柟娉曠殑濮旀墭宸叉坊鍔狅紙GeneratePluginNodeMethods涓凡澶勭悊锛�
         }
 
         public virtual bool ExecuteNode(FlowNode node)
@@ -344,7 +81,7 @@
             if (string.IsNullOrEmpty(node.Description))
                 return false;
 
-            // 浼樺厛妫�鏌ュ姩鎬佸鎵�
+            // 浣跨敤濮旀墭缂撳瓨锛岄伩鍏嶅弽灏勫紑閿�
             if (_nodeDelegates.TryGetValue(node.Description, out var nodeDelegate))
             {
                 try
@@ -358,7 +95,6 @@
                 }
             }
 
-            // 鍏煎鍘熸湁閫昏緫
             return false;
         }
 
@@ -370,7 +106,7 @@
             );
         }
 
-        // 鑾峰彇鎸夌粍鍒嗙粍鐨勫彲鐢ㄨ妭鐐癸紙鍖呭惈鍔ㄦ�佺敓鎴愮殑鎻掍欢鑺傜偣锛�
+        // 鑾峰彇鎸夌粍鍒嗙粍鐨勫彲鐢ㄨ妭鐐�
         public Dictionary<string, List<ToolStripMenuItem>> GetGroupedMenuItems(EventHandler clickHandler)
         {
             var groupedMenuItems = new Dictionary<string, List<ToolStripMenuItem>>();
@@ -381,30 +117,12 @@
 
                 foreach (var method in group.Value)
                 {
-                    string menuText;
-                    string toolTip;
-
-                    // 鍒ゆ柇鏄潤鎬佹柟娉曡繕鏄姩鎬佹柟娉�
-                    if (method is DynamicMethod dynamicMethod)
-                    {
-                        // 鍔ㄦ�佹柟娉曪紙鎻掍欢宸ュ叿锛�
-                        var pluginNode = _pluginNodeMethods.Values.FirstOrDefault(p => p.DisplayName == dynamicMethod.Name);
-                        menuText = pluginNode?.DisplayName ?? dynamicMethod.Name;
-                        toolTip = pluginNode?.Description ?? $"鍔ㄦ�佸伐鍏�: {dynamicMethod.Name}";
-                    }
-                    else
-                    {
-                        // 闈欐�佹柟娉曪紙鍘熸湁Node鐗规�ф柟娉曪級
-                        var nodeAttr = method.GetCustomAttribute<NodeAttribute>();
-                        menuText = nodeAttr?.Name ?? method.Name;
-                        toolTip = nodeAttr?.Description ?? method.Name;
-                    }
-
+                    var nodeAttr = method.GetCustomAttribute<NodeAttribute>();
                     var menuItem = new ToolStripMenuItem
                     {
-                        Text = menuText,
-                        Tag = menuText, // 瀛樺偍鎻忚堪浣滀负鏍囪瘑
-                        ToolTipText = toolTip
+                        Text = nodeAttr.Name,
+                        Tag = nodeAttr.Description, // 瀛樺偍鎻忚堪浣滀负鏍囪瘑
+                        ToolTipText = nodeAttr.Description
                     };
 
                     if (clickHandler != null)
@@ -421,17 +139,15 @@
             return groupedMenuItems;
         }
 
-        // 鑾峰彇鎸夌被鍒垎缁勭殑鑿滃崟椤癸紙鍖呭惈鍔ㄦ�佺敓鎴愮殑鎻掍欢鑺傜偣锛�
+
+        // 鑾峰彇鎸夌被鍒垎缁勭殑鑿滃崟椤�
         public Dictionary<string, List<ToolStripMenuItem>> GetCategorizedMenuItems(EventHandler clickHandler)
         {
             var categorizedMethods = new Dictionary<string, List<MethodInfo>>();
 
-            // 1. 澶勭悊鍘熸湁Node鏂规硶
-            foreach (var method in _nodeMethods.Values.Where(m => !(m is DynamicMethod)))
+            foreach (var method in _nodeMethods.Values)
             {
                 var nodeAttr = method.GetCustomAttribute<NodeAttribute>();
-                if (nodeAttr == null) continue;
-
                 if (!categorizedMethods.ContainsKey(nodeAttr.Category))
                 {
                     categorizedMethods[nodeAttr.Category] = new List<MethodInfo>();
@@ -439,54 +155,20 @@
                 categorizedMethods[nodeAttr.Category].Add(method);
             }
 
-            // 2. 澶勭悊鍔ㄦ�佹彃浠舵柟娉�
-            foreach (var pluginNode in _pluginNodeMethods.Values)
-            {
-                if (!categorizedMethods.ContainsKey(pluginNode.Category))
-                {
-                    categorizedMethods[pluginNode.Category] = new List<MethodInfo>();
-                }
-
-                // 鎵惧埌瀵瑰簲鐨勫姩鎬丮ethodInfo
-                var dynamicMethod = _nodeMethods.Values
-                    .OfType<DynamicMethod>()
-                    .FirstOrDefault(m => m.Name == pluginNode.DisplayName);
-
-                if (dynamicMethod != null)
-                {
-                    categorizedMethods[pluginNode.Category].Add(dynamicMethod);
-                }
-            }
-
-            // 鐢熸垚鑿滃崟椤�
             var categorizedMenuItems = new Dictionary<string, List<ToolStripMenuItem>>();
+
             foreach (var category in categorizedMethods)
             {
                 var menuItems = new List<ToolStripMenuItem>();
 
                 foreach (var method in category.Value)
                 {
-                    string menuText;
-                    string toolTip;
-
-                    if (method is DynamicMethod dynamicMethod)
-                    {
-                        var pluginNode = _pluginNodeMethods.Values.FirstOrDefault(p => p.DisplayName == dynamicMethod.Name);
-                        menuText = pluginNode?.DisplayName ?? dynamicMethod.Name;
-                        toolTip = pluginNode?.Description ?? $"鍔ㄦ�佸伐鍏�: {dynamicMethod.Name}";
-                    }
-                    else
-                    {
-                        var nodeAttr = method.GetCustomAttribute<NodeAttribute>();
-                        menuText = nodeAttr?.Name ?? method.Name;
-                        toolTip = $"{nodeAttr?.Group} - {nodeAttr?.Description}";
-                    }
-
+                    var nodeAttr = method.GetCustomAttribute<NodeAttribute>();
                     var menuItem = new ToolStripMenuItem
                     {
-                        Text = menuText,
-                        Tag = menuText,
-                        ToolTipText = toolTip
+                        Text = nodeAttr.Name,
+                        Tag = nodeAttr.Description,
+                        ToolTipText = $"{nodeAttr.Group} - {nodeAttr.Description}"
                     };
 
                     if (clickHandler != null)
@@ -503,7 +185,6 @@
             return categorizedMenuItems;
         }
 
-        // 鍘熸湁Node鏂规硶
         [Node("寮�濮�", "鎺у埗", "Logic", "寮�濮�")]
         public virtual void 寮�濮�(FlowNode node) { node.Result = true; }
 
@@ -538,7 +219,6 @@
         [Node("骞惰鍒嗘敮缁撴潫", "鎺у埗", "Logic", "骞惰鍒嗘敮缁撴潫")]
         public virtual void 骞惰鍒嗘敮缁撴潫(FlowNode node) { node.Result = true; }
     }
-
     public class FlowContext : IFlowContext
     {
         /// <summary>
@@ -573,9 +253,11 @@
 
         public FlowContext()
         {
+            //GenerateFixedNodeMethods();
             InitializeMethods();
             InitializeDelegates();
         }
+
 
         // 缁熶竴鐨勫姩鎬佽妭鐐规墽琛岃緟鍔╂柟娉曪紙鍙�夛級
         private void RunNodeAsync(FlowNode node)
@@ -672,9 +354,6 @@
             }
         }
 
-        // 淇濈暀鍘熸湁娴嬭瘯鏂规硶锛堝彲閫夛紝涔熷彲浠ョЩ闄わ紝鐢卞姩鎬佺敓鎴愭浛浠o級
-        [Node("娴嬭瘯宸ュ叿", "绠楁硶", "Basic", "娴嬭瘯宸ュ叿")]
-        public void 娴嬭瘯宸ュ叿(FlowNode node) { RunNodeAsync(node); }
     }
 
 }
diff --git a/LB_VisionProcesses/Cameras/2DCameraForm.Designer.cs b/LB_VisionProcesses/Cameras/2DCameraForm.Designer.cs
index 90ab464..4d9aef1 100644
--- a/LB_VisionProcesses/Cameras/2DCameraForm.Designer.cs
+++ b/LB_VisionProcesses/Cameras/2DCameraForm.Designer.cs
@@ -104,18 +104,20 @@
             // 
             cmbBrand.Dock = DockStyle.Fill;
             cmbBrand.FormattingEnabled = true;
-            cmbBrand.Location = new Point(53, 3);
+            cmbBrand.Location = new Point(68, 4);
+            cmbBrand.Margin = new Padding(4);
             cmbBrand.Name = "cmbBrand";
-            cmbBrand.Size = new Size(297, 25);
+            cmbBrand.Size = new Size(381, 28);
             cmbBrand.TabIndex = 0;
             // 
             // cmbSN
             // 
             cmbSN.Dock = DockStyle.Fill;
             cmbSN.FormattingEnabled = true;
-            cmbSN.Location = new Point(53, 3);
+            cmbSN.Location = new Point(68, 4);
+            cmbSN.Margin = new Padding(4);
             cmbSN.Name = "cmbSN";
-            cmbSN.Size = new Size(297, 25);
+            cmbSN.Size = new Size(381, 28);
             cmbSN.TabIndex = 1;
             cmbSN.SelectedIndexChanged += cmbSN_SelectedIndexChanged;
             cmbSN.MouseDown += cmbSN_MouseDown;
@@ -124,9 +126,10 @@
             // 
             label1.AutoSize = true;
             label1.Dock = DockStyle.Fill;
-            label1.Location = new Point(3, 0);
+            label1.Location = new Point(4, 0);
+            label1.Margin = new Padding(4, 0, 4, 0);
             label1.Name = "label1";
-            label1.Size = new Size(44, 34);
+            label1.Size = new Size(56, 39);
             label1.TabIndex = 2;
             label1.Text = "鍝佺墝";
             label1.TextAlign = ContentAlignment.MiddleCenter;
@@ -135,9 +138,10 @@
             // 
             label2.AutoSize = true;
             label2.Dock = DockStyle.Fill;
-            label2.Location = new Point(3, 0);
+            label2.Location = new Point(4, 0);
+            label2.Margin = new Padding(4, 0, 4, 0);
             label2.Name = "label2";
-            label2.Size = new Size(44, 34);
+            label2.Size = new Size(56, 39);
             label2.TabIndex = 3;
             label2.Text = "SN";
             label2.TextAlign = ContentAlignment.MiddleCenter;
@@ -146,9 +150,10 @@
             // 
             btnStartGrab.Dock = DockStyle.Fill;
             btnStartGrab.ForeColor = SystemColors.ControlText;
-            btnStartGrab.Location = new Point(91, 3);
+            btnStartGrab.Location = new Point(117, 4);
+            btnStartGrab.Margin = new Padding(4);
             btnStartGrab.Name = "btnStartGrab";
-            btnStartGrab.Size = new Size(82, 28);
+            btnStartGrab.Size = new Size(105, 31);
             btnStartGrab.TabIndex = 5;
             btnStartGrab.Text = "杩炵画閲囬泦";
             btnStartGrab.UseVisualStyleBackColor = true;
@@ -158,9 +163,10 @@
             // 
             btnCloseGrab.Dock = DockStyle.Fill;
             btnCloseGrab.ForeColor = SystemColors.Desktop;
-            btnCloseGrab.Location = new Point(179, 3);
+            btnCloseGrab.Location = new Point(230, 4);
+            btnCloseGrab.Margin = new Padding(4);
             btnCloseGrab.Name = "btnCloseGrab";
-            btnCloseGrab.Size = new Size(82, 28);
+            btnCloseGrab.Size = new Size(105, 31);
             btnCloseGrab.TabIndex = 6;
             btnCloseGrab.Text = "鍏抽棴閲囬泦";
             btnCloseGrab.UseVisualStyleBackColor = true;
@@ -170,9 +176,10 @@
             // 
             btnGrabOnce.Dock = DockStyle.Fill;
             btnGrabOnce.ForeColor = SystemColors.ControlText;
-            btnGrabOnce.Location = new Point(3, 3);
+            btnGrabOnce.Location = new Point(4, 4);
+            btnGrabOnce.Margin = new Padding(4);
             btnGrabOnce.Name = "btnGrabOnce";
-            btnGrabOnce.Size = new Size(82, 28);
+            btnGrabOnce.Size = new Size(105, 31);
             btnGrabOnce.TabIndex = 7;
             btnGrabOnce.Text = "鍗曞紶閲囬泦";
             btnGrabOnce.UseVisualStyleBackColor = true;
@@ -182,9 +189,10 @@
             // 
             btnOpen.Dock = DockStyle.Fill;
             btnOpen.ForeColor = SystemColors.ControlText;
-            btnOpen.Location = new Point(3, 3);
+            btnOpen.Location = new Point(4, 4);
+            btnOpen.Margin = new Padding(4);
             btnOpen.Name = "btnOpen";
-            btnOpen.Size = new Size(82, 28);
+            btnOpen.Size = new Size(105, 31);
             btnOpen.TabIndex = 8;
             btnOpen.Text = "鎵撳紑";
             btnOpen.UseVisualStyleBackColor = true;
@@ -194,9 +202,10 @@
             // 
             btnClose.Dock = DockStyle.Fill;
             btnClose.ForeColor = SystemColors.ControlText;
-            btnClose.Location = new Point(91, 3);
+            btnClose.Location = new Point(117, 4);
+            btnClose.Margin = new Padding(4);
             btnClose.Name = "btnClose";
-            btnClose.Size = new Size(82, 28);
+            btnClose.Size = new Size(105, 31);
             btnClose.TabIndex = 9;
             btnClose.Text = "鍏抽棴";
             btnClose.UseVisualStyleBackColor = true;
@@ -206,9 +215,10 @@
             // 
             label5.AutoSize = true;
             label5.Dock = DockStyle.Fill;
-            label5.Location = new Point(3, 0);
+            label5.Location = new Point(4, 0);
+            label5.Margin = new Padding(4, 0, 4, 0);
             label5.Name = "label5";
-            label5.Size = new Size(114, 34);
+            label5.Size = new Size(146, 39);
             label5.TabIndex = 15;
             label5.Text = "鍙栧浘鏁伴噺锛�";
             label5.TextAlign = ContentAlignment.MiddleCenter;
@@ -217,9 +227,10 @@
             // 
             lblPicCount.AutoSize = true;
             lblPicCount.Dock = DockStyle.Fill;
-            lblPicCount.Location = new Point(123, 0);
+            lblPicCount.Location = new Point(158, 0);
+            lblPicCount.Margin = new Padding(4, 0, 4, 0);
             lblPicCount.Name = "lblPicCount";
-            lblPicCount.Size = new Size(227, 34);
+            lblPicCount.Size = new Size(291, 39);
             lblPicCount.TabIndex = 16;
             lblPicCount.Text = "0";
             lblPicCount.TextAlign = ContentAlignment.MiddleLeft;
@@ -227,18 +238,20 @@
             // txtGain
             // 
             txtGain.Dock = DockStyle.Fill;
-            txtGain.Location = new Point(53, 3);
+            txtGain.Location = new Point(68, 4);
+            txtGain.Margin = new Padding(4);
             txtGain.Name = "txtGain";
-            txtGain.Size = new Size(297, 23);
+            txtGain.Size = new Size(381, 27);
             txtGain.TabIndex = 21;
             txtGain.TextChanged += txtGain_TextChanged;
             // 
             // txtExp
             // 
             txtExp.Dock = DockStyle.Fill;
-            txtExp.Location = new Point(53, 3);
+            txtExp.Location = new Point(68, 4);
+            txtExp.Margin = new Padding(4);
             txtExp.Name = "txtExp";
-            txtExp.Size = new Size(297, 23);
+            txtExp.Size = new Size(381, 27);
             txtExp.TabIndex = 20;
             txtExp.TextChanged += txtExp_TextChanged;
             // 
@@ -246,9 +259,10 @@
             // 
             label4.AutoSize = true;
             label4.Dock = DockStyle.Fill;
-            label4.Location = new Point(3, 0);
+            label4.Location = new Point(4, 0);
+            label4.Margin = new Padding(4, 0, 4, 0);
             label4.Name = "label4";
-            label4.Size = new Size(44, 34);
+            label4.Size = new Size(56, 39);
             label4.TabIndex = 19;
             label4.Text = "澧炵泭";
             label4.TextAlign = ContentAlignment.MiddleCenter;
@@ -257,9 +271,10 @@
             // 
             label3.AutoSize = true;
             label3.Dock = DockStyle.Fill;
-            label3.Location = new Point(3, 0);
+            label3.Location = new Point(4, 0);
+            label3.Margin = new Padding(4, 0, 4, 0);
             label3.Name = "label3";
-            label3.Size = new Size(44, 34);
+            label3.Size = new Size(56, 39);
             label3.TabIndex = 18;
             label3.Text = "鏇濆厜";
             label3.TextAlign = ContentAlignment.MiddleCenter;
@@ -271,8 +286,10 @@
             groupBox1.Dock = DockStyle.Fill;
             groupBox1.ForeColor = SystemColors.Control;
             groupBox1.Location = new Point(0, 0);
+            groupBox1.Margin = new Padding(4);
             groupBox1.Name = "groupBox1";
-            groupBox1.Size = new Size(486, 591);
+            groupBox1.Padding = new Padding(4);
+            groupBox1.Size = new Size(626, 695);
             groupBox1.TabIndex = 17;
             groupBox1.TabStop = false;
             groupBox1.Text = "瀹炴椂閲囬泦";
@@ -280,18 +297,20 @@
             // panel_Picture
             // 
             panel_Picture.Dock = DockStyle.Fill;
-            panel_Picture.Location = new Point(3, 19);
+            panel_Picture.Location = new Point(4, 24);
+            panel_Picture.Margin = new Padding(4);
             panel_Picture.Name = "panel_Picture";
-            panel_Picture.Size = new Size(480, 569);
+            panel_Picture.Size = new Size(618, 667);
             panel_Picture.TabIndex = 0;
             // 
             // radioButtonSoft
             // 
             radioButtonSoft.AutoSize = true;
             radioButtonSoft.Dock = DockStyle.Fill;
-            radioButtonSoft.Location = new Point(3, 123);
+            radioButtonSoft.Location = new Point(4, 145);
+            radioButtonSoft.Margin = new Padding(4);
             radioButtonSoft.Name = "radioButtonSoft";
-            radioButtonSoft.Size = new Size(353, 34);
+            radioButtonSoft.Size = new Size(453, 39);
             radioButtonSoft.TabIndex = 23;
             radioButtonSoft.TabStop = true;
             radioButtonSoft.Text = "杞Е鍙�";
@@ -302,9 +321,10 @@
             // 
             radioButtonHard.AutoSize = true;
             radioButtonHard.Dock = DockStyle.Fill;
-            radioButtonHard.Location = new Point(3, 203);
+            radioButtonHard.Location = new Point(4, 239);
+            radioButtonHard.Margin = new Padding(4);
             radioButtonHard.Name = "radioButtonHard";
-            radioButtonHard.Size = new Size(353, 34);
+            radioButtonHard.Size = new Size(453, 39);
             radioButtonHard.TabIndex = 24;
             radioButtonHard.TabStop = true;
             radioButtonHard.Text = "纭Е鍙�";
@@ -313,7 +333,8 @@
             // splitContainer1
             // 
             splitContainer1.Dock = DockStyle.Fill;
-            splitContainer1.Location = new Point(5, 5);
+            splitContainer1.Location = new Point(6, 6);
+            splitContainer1.Margin = new Padding(4);
             splitContainer1.Name = "splitContainer1";
             // 
             // splitContainer1.Panel1
@@ -323,8 +344,9 @@
             // splitContainer1.Panel2
             // 
             splitContainer1.Panel2.Controls.Add(groupBox1);
-            splitContainer1.Size = new Size(855, 591);
-            splitContainer1.SplitterDistance = 365;
+            splitContainer1.Size = new Size(1100, 695);
+            splitContainer1.SplitterDistance = 469;
+            splitContainer1.SplitterWidth = 5;
             splitContainer1.TabIndex = 19;
             // 
             // groupBox2
@@ -334,9 +356,11 @@
             groupBox2.Dock = DockStyle.Fill;
             groupBox2.ForeColor = SystemColors.Control;
             groupBox2.Location = new Point(0, 0);
-            groupBox2.MinimumSize = new Size(261, 61);
+            groupBox2.Margin = new Padding(4);
+            groupBox2.MinimumSize = new Size(336, 72);
             groupBox2.Name = "groupBox2";
-            groupBox2.Size = new Size(365, 591);
+            groupBox2.Padding = new Padding(4);
+            groupBox2.Size = new Size(469, 695);
             groupBox2.TabIndex = 0;
             groupBox2.TabStop = false;
             groupBox2.Text = "鐩告満鍙傛暟";
@@ -360,7 +384,8 @@
             tableLayoutPanel2.Controls.Add(tableLayoutPanel9, 0, 10);
             tableLayoutPanel2.Controls.Add(tableLayoutPanel10, 0, 9);
             tableLayoutPanel2.Dock = DockStyle.Fill;
-            tableLayoutPanel2.Location = new Point(3, 19);
+            tableLayoutPanel2.Location = new Point(4, 24);
+            tableLayoutPanel2.Margin = new Padding(4);
             tableLayoutPanel2.Name = "tableLayoutPanel2";
             tableLayoutPanel2.RowCount = 14;
             tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 7.14301062F));
@@ -377,38 +402,40 @@
             tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 7.14301062F));
             tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 7.143011F));
             tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 7.14086771F));
-            tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
-            tableLayoutPanel2.Size = new Size(359, 569);
+            tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Absolute, 24F));
+            tableLayoutPanel2.Size = new Size(461, 667);
             tableLayoutPanel2.TabIndex = 25;
             // 
             // tableLayoutPanel3
             // 
             tableLayoutPanel3.ColumnCount = 2;
-            tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
+            tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 64F));
             tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
             tableLayoutPanel3.Controls.Add(label1, 0, 0);
             tableLayoutPanel3.Controls.Add(cmbBrand, 1, 0);
             tableLayoutPanel3.Dock = DockStyle.Fill;
-            tableLayoutPanel3.Location = new Point(3, 3);
+            tableLayoutPanel3.Location = new Point(4, 4);
+            tableLayoutPanel3.Margin = new Padding(4);
             tableLayoutPanel3.Name = "tableLayoutPanel3";
             tableLayoutPanel3.RowCount = 1;
             tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel3.Size = new Size(353, 34);
+            tableLayoutPanel3.Size = new Size(453, 39);
             tableLayoutPanel3.TabIndex = 0;
             // 
             // tableLayoutPanel4
             // 
             tableLayoutPanel4.ColumnCount = 2;
-            tableLayoutPanel4.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
+            tableLayoutPanel4.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 64F));
             tableLayoutPanel4.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
             tableLayoutPanel4.Controls.Add(label2, 0, 0);
             tableLayoutPanel4.Controls.Add(cmbSN, 1, 0);
             tableLayoutPanel4.Dock = DockStyle.Fill;
-            tableLayoutPanel4.Location = new Point(3, 43);
+            tableLayoutPanel4.Location = new Point(4, 51);
+            tableLayoutPanel4.Margin = new Padding(4);
             tableLayoutPanel4.Name = "tableLayoutPanel4";
             tableLayoutPanel4.RowCount = 1;
             tableLayoutPanel4.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel4.Size = new Size(353, 34);
+            tableLayoutPanel4.Size = new Size(453, 39);
             tableLayoutPanel4.TabIndex = 1;
             // 
             // tableLayoutPanel5
@@ -422,11 +449,12 @@
             tableLayoutPanel5.Controls.Add(btnClose, 1, 0);
             tableLayoutPanel5.Controls.Add(btnEdit, 3, 0);
             tableLayoutPanel5.Dock = DockStyle.Fill;
-            tableLayoutPanel5.Location = new Point(3, 83);
+            tableLayoutPanel5.Location = new Point(4, 98);
+            tableLayoutPanel5.Margin = new Padding(4);
             tableLayoutPanel5.Name = "tableLayoutPanel5";
             tableLayoutPanel5.RowCount = 1;
             tableLayoutPanel5.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel5.Size = new Size(353, 34);
+            tableLayoutPanel5.Size = new Size(453, 39);
             tableLayoutPanel5.TabIndex = 2;
             // 
             // btnEdit
@@ -434,9 +462,10 @@
             btnEdit.Dock = DockStyle.Fill;
             btnEdit.Enabled = false;
             btnEdit.ForeColor = SystemColors.ControlText;
-            btnEdit.Location = new Point(267, 3);
+            btnEdit.Location = new Point(343, 4);
+            btnEdit.Margin = new Padding(4);
             btnEdit.Name = "btnEdit";
-            btnEdit.Size = new Size(83, 28);
+            btnEdit.Size = new Size(106, 31);
             btnEdit.TabIndex = 10;
             btnEdit.Text = "缂栬緫";
             btnEdit.UseVisualStyleBackColor = true;
@@ -454,21 +483,22 @@
             tableLayoutPanel6.Controls.Add(btnCloseGrab, 2, 0);
             tableLayoutPanel6.Controls.Add(btnSaveImage, 3, 0);
             tableLayoutPanel6.Dock = DockStyle.Fill;
-            tableLayoutPanel6.Location = new Point(3, 163);
+            tableLayoutPanel6.Location = new Point(4, 192);
+            tableLayoutPanel6.Margin = new Padding(4);
             tableLayoutPanel6.Name = "tableLayoutPanel6";
             tableLayoutPanel6.RowCount = 1;
             tableLayoutPanel6.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel6.Size = new Size(353, 34);
+            tableLayoutPanel6.Size = new Size(453, 39);
             tableLayoutPanel6.TabIndex = 24;
             // 
             // btnSaveImage
             // 
             btnSaveImage.Dock = DockStyle.Fill;
             btnSaveImage.ForeColor = SystemColors.Desktop;
-            btnSaveImage.Location = new Point(266, 2);
-            btnSaveImage.Margin = new Padding(2);
+            btnSaveImage.Location = new Point(342, 2);
+            btnSaveImage.Margin = new Padding(3, 2, 3, 2);
             btnSaveImage.Name = "btnSaveImage";
-            btnSaveImage.Size = new Size(85, 30);
+            btnSaveImage.Size = new Size(108, 35);
             btnSaveImage.TabIndex = 8;
             btnSaveImage.Text = "淇濆瓨鍥剧墖";
             btnSaveImage.UseVisualStyleBackColor = true;
@@ -477,31 +507,33 @@
             // tableLayoutPanel7
             // 
             tableLayoutPanel7.ColumnCount = 2;
-            tableLayoutPanel7.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
+            tableLayoutPanel7.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 64F));
             tableLayoutPanel7.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
             tableLayoutPanel7.Controls.Add(label3, 0, 0);
             tableLayoutPanel7.Controls.Add(txtExp, 1, 0);
             tableLayoutPanel7.Dock = DockStyle.Fill;
-            tableLayoutPanel7.Location = new Point(3, 283);
+            tableLayoutPanel7.Location = new Point(4, 333);
+            tableLayoutPanel7.Margin = new Padding(4);
             tableLayoutPanel7.Name = "tableLayoutPanel7";
             tableLayoutPanel7.RowCount = 1;
             tableLayoutPanel7.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
-            tableLayoutPanel7.Size = new Size(353, 34);
+            tableLayoutPanel7.Size = new Size(453, 39);
             tableLayoutPanel7.TabIndex = 25;
             // 
             // tableLayoutPanel8
             // 
             tableLayoutPanel8.ColumnCount = 2;
-            tableLayoutPanel8.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
+            tableLayoutPanel8.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 64F));
             tableLayoutPanel8.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
             tableLayoutPanel8.Controls.Add(label4, 0, 0);
             tableLayoutPanel8.Controls.Add(txtGain, 1, 0);
             tableLayoutPanel8.Dock = DockStyle.Fill;
-            tableLayoutPanel8.Location = new Point(3, 323);
+            tableLayoutPanel8.Location = new Point(4, 380);
+            tableLayoutPanel8.Margin = new Padding(4);
             tableLayoutPanel8.Name = "tableLayoutPanel8";
             tableLayoutPanel8.RowCount = 1;
             tableLayoutPanel8.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel8.Size = new Size(353, 34);
+            tableLayoutPanel8.Size = new Size(453, 39);
             tableLayoutPanel8.TabIndex = 26;
             // 
             // tableLayoutPanel1
@@ -514,19 +546,21 @@
             tableLayoutPanel1.Controls.Add(ckbUpParams, 1, 0);
             tableLayoutPanel1.Controls.Add(ckbRegrab, 2, 0);
             tableLayoutPanel1.Dock = DockStyle.Fill;
-            tableLayoutPanel1.Location = new Point(3, 243);
+            tableLayoutPanel1.Location = new Point(4, 286);
+            tableLayoutPanel1.Margin = new Padding(4);
             tableLayoutPanel1.Name = "tableLayoutPanel1";
             tableLayoutPanel1.RowCount = 1;
             tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel1.Size = new Size(353, 34);
+            tableLayoutPanel1.Size = new Size(453, 39);
             tableLayoutPanel1.TabIndex = 29;
             // 
             // btnStartHard
             // 
             btnStartHard.Dock = DockStyle.Fill;
-            btnStartHard.Location = new Point(3, 3);
+            btnStartHard.Location = new Point(4, 4);
+            btnStartHard.Margin = new Padding(4);
             btnStartHard.Name = "btnStartHard";
-            btnStartHard.Size = new Size(64, 28);
+            btnStartHard.Size = new Size(82, 31);
             btnStartHard.TabIndex = 22;
             btnStartHard.Text = "绛夊緟瑙﹀彂";
             btnStartHard.UseVisualStyleBackColor = true;
@@ -536,9 +570,10 @@
             // 
             ckbUpParams.AutoSize = true;
             ckbUpParams.Dock = DockStyle.Fill;
-            ckbUpParams.Location = new Point(73, 3);
+            ckbUpParams.Location = new Point(94, 4);
+            ckbUpParams.Margin = new Padding(4);
             ckbUpParams.Name = "ckbUpParams";
-            ckbUpParams.Size = new Size(135, 28);
+            ckbUpParams.Size = new Size(173, 31);
             ckbUpParams.TabIndex = 23;
             ckbUpParams.Text = "鏄惁姣忔鍐欏叆鍙傛暟";
             ckbUpParams.UseVisualStyleBackColor = true;
@@ -547,9 +582,10 @@
             // 
             ckbRegrab.AutoSize = true;
             ckbRegrab.Dock = DockStyle.Fill;
-            ckbRegrab.Location = new Point(214, 3);
+            ckbRegrab.Location = new Point(275, 4);
+            ckbRegrab.Margin = new Padding(4);
             ckbRegrab.Name = "ckbRegrab";
-            ckbRegrab.Size = new Size(136, 28);
+            ckbRegrab.Size = new Size(174, 31);
             ckbRegrab.TabIndex = 24;
             ckbRegrab.Text = "鏄惁澶辫触閲嶆柊鍙栧浘";
             ckbRegrab.UseVisualStyleBackColor = true;
@@ -557,25 +593,27 @@
             // tableLayoutPanel12
             // 
             tableLayoutPanel12.ColumnCount = 2;
-            tableLayoutPanel12.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 120F));
+            tableLayoutPanel12.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 154F));
             tableLayoutPanel12.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
             tableLayoutPanel12.Controls.Add(lblCapTime, 1, 0);
             tableLayoutPanel12.Controls.Add(label7, 0, 0);
             tableLayoutPanel12.Dock = DockStyle.Fill;
-            tableLayoutPanel12.Location = new Point(3, 523);
+            tableLayoutPanel12.Location = new Point(4, 615);
+            tableLayoutPanel12.Margin = new Padding(4);
             tableLayoutPanel12.Name = "tableLayoutPanel12";
             tableLayoutPanel12.RowCount = 1;
             tableLayoutPanel12.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel12.Size = new Size(353, 43);
+            tableLayoutPanel12.Size = new Size(453, 48);
             tableLayoutPanel12.TabIndex = 31;
             // 
             // lblCapTime
             // 
             lblCapTime.AutoSize = true;
             lblCapTime.Dock = DockStyle.Fill;
-            lblCapTime.Location = new Point(123, 0);
+            lblCapTime.Location = new Point(158, 0);
+            lblCapTime.Margin = new Padding(4, 0, 4, 0);
             lblCapTime.Name = "lblCapTime";
-            lblCapTime.Size = new Size(227, 43);
+            lblCapTime.Size = new Size(291, 48);
             lblCapTime.TabIndex = 16;
             lblCapTime.Text = "0ms";
             lblCapTime.TextAlign = ContentAlignment.MiddleLeft;
@@ -584,9 +622,10 @@
             // 
             label7.AutoSize = true;
             label7.Dock = DockStyle.Fill;
-            label7.Location = new Point(3, 0);
+            label7.Location = new Point(4, 0);
+            label7.Margin = new Padding(4, 0, 4, 0);
             label7.Name = "label7";
-            label7.Size = new Size(114, 43);
+            label7.Size = new Size(146, 48);
             label7.TabIndex = 15;
             label7.Text = "鍙栧浘鏃堕棿锛�";
             label7.TextAlign = ContentAlignment.MiddleCenter;
@@ -594,16 +633,17 @@
             // tableLayoutPanel11
             // 
             tableLayoutPanel11.ColumnCount = 2;
-            tableLayoutPanel11.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 120F));
+            tableLayoutPanel11.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 154F));
             tableLayoutPanel11.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
             tableLayoutPanel11.Controls.Add(label5, 0, 0);
             tableLayoutPanel11.Controls.Add(lblPicCount, 1, 0);
             tableLayoutPanel11.Dock = DockStyle.Fill;
-            tableLayoutPanel11.Location = new Point(3, 483);
+            tableLayoutPanel11.Location = new Point(4, 568);
+            tableLayoutPanel11.Margin = new Padding(4);
             tableLayoutPanel11.Name = "tableLayoutPanel11";
             tableLayoutPanel11.RowCount = 1;
             tableLayoutPanel11.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel11.Size = new Size(353, 34);
+            tableLayoutPanel11.Size = new Size(453, 39);
             tableLayoutPanel11.TabIndex = 30;
             // 
             // cmbImagesPath
@@ -612,9 +652,10 @@
             cmbImagesPath.Dock = DockStyle.Fill;
             cmbImagesPath.ForeColor = SystemColors.ControlText;
             cmbImagesPath.FormattingEnabled = true;
-            cmbImagesPath.Location = new Point(3, 443);
+            cmbImagesPath.Location = new Point(4, 521);
+            cmbImagesPath.Margin = new Padding(4);
             cmbImagesPath.Name = "cmbImagesPath";
-            cmbImagesPath.Size = new Size(353, 25);
+            cmbImagesPath.Size = new Size(453, 28);
             cmbImagesPath.TabIndex = 0;
             cmbImagesPath.SelectedIndexChanged += cmbImagesPath_SelectedIndexChanged;
             cmbImagesPath.MouseHover += cmbImagesPath_MouseHover;
@@ -629,20 +670,22 @@
             tableLayoutPanel9.Controls.Add(btnAddImages, 1, 0);
             tableLayoutPanel9.Controls.Add(btnLocalGrab, 2, 0);
             tableLayoutPanel9.Dock = DockStyle.Fill;
-            tableLayoutPanel9.Location = new Point(3, 403);
+            tableLayoutPanel9.Location = new Point(4, 474);
+            tableLayoutPanel9.Margin = new Padding(4);
             tableLayoutPanel9.Name = "tableLayoutPanel9";
             tableLayoutPanel9.RowCount = 1;
             tableLayoutPanel9.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel9.Size = new Size(353, 34);
+            tableLayoutPanel9.Size = new Size(453, 39);
             tableLayoutPanel9.TabIndex = 27;
             // 
             // ckbLocalTest
             // 
             ckbLocalTest.AutoSize = true;
             ckbLocalTest.Dock = DockStyle.Fill;
-            ckbLocalTest.Location = new Point(3, 3);
+            ckbLocalTest.Location = new Point(4, 4);
+            ckbLocalTest.Margin = new Padding(4);
             ckbLocalTest.Name = "ckbLocalTest";
-            ckbLocalTest.Size = new Size(111, 28);
+            ckbLocalTest.Size = new Size(142, 31);
             ckbLocalTest.TabIndex = 0;
             ckbLocalTest.Text = "鏈湴鍙栧浘";
             ckbLocalTest.UseVisualStyleBackColor = true;
@@ -651,9 +694,10 @@
             // 
             btnAddImages.Dock = DockStyle.Fill;
             btnAddImages.ForeColor = SystemColors.Desktop;
-            btnAddImages.Location = new Point(120, 3);
+            btnAddImages.Location = new Point(154, 4);
+            btnAddImages.Margin = new Padding(4);
             btnAddImages.Name = "btnAddImages";
-            btnAddImages.Size = new Size(111, 28);
+            btnAddImages.Size = new Size(142, 31);
             btnAddImages.TabIndex = 1;
             btnAddImages.Text = "娣诲姞鍥剧墖";
             btnAddImages.UseVisualStyleBackColor = true;
@@ -663,9 +707,10 @@
             // 
             btnLocalGrab.Dock = DockStyle.Fill;
             btnLocalGrab.ForeColor = SystemColors.Desktop;
-            btnLocalGrab.Location = new Point(237, 3);
+            btnLocalGrab.Location = new Point(304, 4);
+            btnLocalGrab.Margin = new Padding(4);
             btnLocalGrab.Name = "btnLocalGrab";
-            btnLocalGrab.Size = new Size(113, 28);
+            btnLocalGrab.Size = new Size(145, 31);
             btnLocalGrab.TabIndex = 2;
             btnLocalGrab.Text = "鏈湴鍙栧浘";
             btnLocalGrab.UseVisualStyleBackColor = true;
@@ -674,25 +719,27 @@
             // tableLayoutPanel10
             // 
             tableLayoutPanel10.ColumnCount = 2;
-            tableLayoutPanel10.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
+            tableLayoutPanel10.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 64F));
             tableLayoutPanel10.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
             tableLayoutPanel10.Controls.Add(label6, 0, 0);
             tableLayoutPanel10.Controls.Add(txtTimeout, 1, 0);
             tableLayoutPanel10.Dock = DockStyle.Fill;
-            tableLayoutPanel10.Location = new Point(3, 363);
+            tableLayoutPanel10.Location = new Point(4, 427);
+            tableLayoutPanel10.Margin = new Padding(4);
             tableLayoutPanel10.Name = "tableLayoutPanel10";
             tableLayoutPanel10.RowCount = 1;
             tableLayoutPanel10.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel10.Size = new Size(353, 34);
+            tableLayoutPanel10.Size = new Size(453, 39);
             tableLayoutPanel10.TabIndex = 32;
             // 
             // label6
             // 
             label6.AutoSize = true;
             label6.Dock = DockStyle.Fill;
-            label6.Location = new Point(3, 0);
+            label6.Location = new Point(4, 0);
+            label6.Margin = new Padding(4, 0, 4, 0);
             label6.Name = "label6";
-            label6.Size = new Size(44, 34);
+            label6.Size = new Size(56, 39);
             label6.TabIndex = 0;
             label6.Text = "瓒呮椂";
             label6.TextAlign = ContentAlignment.MiddleCenter;
@@ -700,9 +747,10 @@
             // txtTimeout
             // 
             txtTimeout.Dock = DockStyle.Fill;
-            txtTimeout.Location = new Point(53, 3);
+            txtTimeout.Location = new Point(68, 4);
+            txtTimeout.Margin = new Padding(4);
             txtTimeout.Name = "txtTimeout";
-            txtTimeout.Size = new Size(297, 23);
+            txtTimeout.Size = new Size(381, 27);
             txtTimeout.TabIndex = 1;
             // 
             // theme_2DCameraForm
@@ -715,15 +763,17 @@
             theme_2DCameraForm.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
             theme_2DCameraForm.Image = (Image)resources.GetObject("theme_2DCameraForm.Image");
             theme_2DCameraForm.Location = new Point(0, 0);
+            theme_2DCameraForm.Margin = new Padding(4);
             theme_2DCameraForm.Name = "theme_2DCameraForm";
-            theme_2DCameraForm.Padding = new Padding(10, 70, 10, 9);
+            theme_2DCameraForm.Padding = new Padding(13, 82, 13, 11);
             theme_2DCameraForm.RoundCorners = true;
             theme_2DCameraForm.Sizable = true;
-            theme_2DCameraForm.Size = new Size(885, 680);
+            theme_2DCameraForm.Size = new Size(1138, 800);
             theme_2DCameraForm.SmartBounds = true;
             theme_2DCameraForm.StartPosition = FormStartPosition.WindowsDefaultLocation;
             theme_2DCameraForm.TabIndex = 20;
             theme_2DCameraForm.Text = "2D鐩告満璁剧疆鐣岄潰";
+            theme_2DCameraForm.Click += theme_2DCameraForm_Click;
             // 
             // controlBox1
             // 
@@ -735,7 +785,8 @@
             controlBox1.EnableMaximizeButton = false;
             controlBox1.EnableMinimizeButton = false;
             controlBox1.ForeColor = Color.FromArgb(155, 155, 155);
-            controlBox1.Location = new Point(785, 18);
+            controlBox1.Location = new Point(1009, 18);
+            controlBox1.Margin = new Padding(4);
             controlBox1.MaximizeHoverColor = Color.FromArgb(74, 74, 74);
             controlBox1.MinimizeHoverColor = Color.FromArgb(63, 63, 65);
             controlBox1.Name = "controlBox1";
@@ -749,22 +800,24 @@
             panel_2DCameraForm.Controls.Add(splitContainer1);
             panel_2DCameraForm.Dock = DockStyle.Fill;
             panel_2DCameraForm.EdgeColor = Color.FromArgb(32, 41, 50);
-            panel_2DCameraForm.Location = new Point(10, 70);
+            panel_2DCameraForm.Location = new Point(13, 82);
+            panel_2DCameraForm.Margin = new Padding(4);
             panel_2DCameraForm.Name = "panel_2DCameraForm";
-            panel_2DCameraForm.Padding = new Padding(5);
-            panel_2DCameraForm.Size = new Size(865, 601);
+            panel_2DCameraForm.Padding = new Padding(6);
+            panel_2DCameraForm.Size = new Size(1112, 707);
             panel_2DCameraForm.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
             panel_2DCameraForm.TabIndex = 20;
             panel_2DCameraForm.Text = "panel2";
             // 
             // CameraForm
             // 
-            AutoScaleDimensions = new SizeF(7F, 17F);
+            AutoScaleDimensions = new SizeF(9F, 20F);
             AutoScaleMode = AutoScaleMode.Font;
-            ClientSize = new Size(885, 680);
+            ClientSize = new Size(1138, 800);
             Controls.Add(theme_2DCameraForm);
             FormBorderStyle = FormBorderStyle.None;
-            MinimumSize = new Size(261, 61);
+            Margin = new Padding(4);
+            MinimumSize = new Size(336, 72);
             Name = "CameraForm";
             Text = "2D鐩告満璁剧疆鐣岄潰";
             TransparencyKey = Color.Fuchsia;
diff --git a/LB_VisionProcesses/Cameras/2DCameraForm.cs b/LB_VisionProcesses/Cameras/2DCameraForm.cs
index 1bbdd63..958dada 100644
--- a/LB_VisionProcesses/Cameras/2DCameraForm.cs
+++ b/LB_VisionProcesses/Cameras/2DCameraForm.cs
@@ -154,7 +154,7 @@
                 switch (brand)
                 {
                     case CameraBrand.HRCamera:
-                        //camera = new HRCamera();
+                        camera = new HRCamera();
                         break;
                     case CameraBrand.LBCamera:
                         //camera = new LBCamera();
@@ -224,7 +224,7 @@
                         //camera = new LBCamera();
                         break;
                     case CameraBrand.HRCamera:
-                        //camera = new HRCamera();
+                        camera = new HRCamera();
                         break;
                     default:
                         Debug.WriteLine($"銆恵DateTime.Now:HH:mm:ss.fff}銆戞湭鐭ュ搧鐗�");
@@ -649,12 +649,17 @@
 
         private void controlBox_2DCameraForm_Click(object sender, EventArgs e)
         {
-            
+
         }
 
         private void dungeonControlBox_2DCameraForm_Click(object sender, EventArgs e)
         {
-           // this.Close();
+            // this.Close();
+        }
+
+        private void theme_2DCameraForm_Click(object sender, EventArgs e)
+        {
+
         }
     }
 }
diff --git a/LB_VisionProcesses/Cameras/HRCamera.cs b/LB_VisionProcesses/Cameras/HRCamera.cs
new file mode 100644
index 0000000..239a4e4
--- /dev/null
+++ b/LB_VisionProcesses/Cameras/HRCamera.cs
@@ -0,0 +1,920 @@
+锘縰sing MVSDK_Net;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Windows.Forms;
+
+namespace LB_VisionProcesses.Cameras
+{
+    /// <summary>
+    /// 鍗庣澘2D宸ヤ笟鐩告満瀹炵幇绫�
+    /// 鍩轰簬MVSDK_Net SDK灏佽
+    /// </summary>
+    public class HRCamera : BaseCamera
+    {
+        #region 绉佹湁瀛楁
+        
+        private MyCamera _camera; // 鍗庣澘鐩告満璁惧瀵硅薄
+        private Thread _grabThread; // 鍥惧儚閲囬泦绾跨▼
+        private bool _isGrabbing; // 閲囬泦鐘舵�佹爣蹇�
+        private bool _threadRunning; // 绾跨▼杩愯鏍囧織
+        private Thread _callbackThread; // 鍥炶皟澶勭悊绾跨▼
+        private List<IMVDefine.IMV_Frame> _frameList; // 鍥惧儚缂撳瓨鍒楄〃
+        private readonly object _frameLock = new object(); // 甯х紦瀛橀攣
+        
+        // CopyMemory API澹版槑
+        [System.Runtime.InteropServices.DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
+        private static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
+        
+        #endregion
+
+        #region 鏋勯�犲嚱鏁板拰鏋愭瀯鍑芥暟
+        
+        /// <summary>
+        /// 鏋勯�犲嚱鏁�
+        /// </summary>
+        public HRCamera()
+        {
+            _camera = new MyCamera();
+            _frameList = new List<IMVDefine.IMV_Frame>();
+            Brand = CameraBrand.HRCamera;
+            _isGrabbing = false;
+            _threadRunning = false;
+        }
+        
+        /// <summary>
+        /// 鏋愭瀯鍑芥暟
+        /// </summary>
+        ~HRCamera()
+        {
+            Dispose(false);
+        }
+        
+        #endregion
+
+        #region 璁惧绠$悊鎿嶄綔
+        
+        /// <summary>
+        /// 鑾峰彇鐩告満SN鏋氫妇鍒楄〃
+        /// </summary>
+        /// <returns>鐩告満SN鍒楄〃</returns>
+        public override List<string> GetListEnum()
+        {
+            List<string> cameraList = new List<string>();
+            
+            try
+            {
+                // 鏋氫妇鎵�鏈夎澶�
+                IMVDefine.IMV_DeviceList deviceList = new IMVDefine.IMV_DeviceList();
+                IMVDefine.IMV_EInterfaceType interfaceType = IMVDefine.IMV_EInterfaceType.interfaceTypeAll;
+                
+                int result = MyCamera.IMV_EnumDevices(ref deviceList, (uint)interfaceType);
+                
+                if (result == IMVDefine.IMV_OK && deviceList.nDevNum > 0)
+                {
+                    for (int i = 0; i < deviceList.nDevNum; i++)
+                    {
+                        IMVDefine.IMV_DeviceInfo deviceInfo = (IMVDefine.IMV_DeviceInfo)
+                            Marshal.PtrToStructure(
+                                deviceList.pDevInfo + Marshal.SizeOf(typeof(IMVDefine.IMV_DeviceInfo)) * i,
+                                typeof(IMVDefine.IMV_DeviceInfo));
+                        
+                        string cameraInfo = $"{deviceInfo.cameraName}[{deviceInfo.serialNumber}]";
+                        cameraList.Add(cameraInfo); 
+                    }
+                }
+                else
+                {
+                    // 璁板綍鏃ュ織鎴栨姏鍑哄紓甯�
+                    throw new Exception($"鏋氫妇璁惧澶辫触锛岄敊璇爜锛歿result}");
+                }
+            }
+            catch (Exception ex)
+            { 
+                // 璁板綍閿欒鏃ュ織
+                System.Diagnostics.Debug.WriteLine($"鑾峰彇鐩告満鍒楄〃澶辫触锛歿ex.Message}");
+                throw;
+            }
+            
+            return cameraList;
+        }
+        
+        /// <summary>
+        /// 鍒濆鍖栫浉鏈鸿澶�
+        /// </summary>
+        /// <param name="SN">鐩告満搴忓垪鍙�</param>
+        /// <param name="Handle">绐楀彛鍙ユ焺锛堝彲閫夛級</param>
+        /// <returns>鍒濆鍖栨槸鍚︽垚鍔�</returns>
+        public override bool InitDevice(string SN, object Handle = null)
+        {
+            try
+            {
+                // 濡傛灉鐩告満宸叉墦寮�锛屽厛鍏抽棴
+                if (_camera != null && _camera.IMV_IsOpen())
+                {
+                    CloseDevice();
+                }
+                
+                // 鏋氫妇璁惧骞跺尮閰峉N
+                List<string> cameraList = GetListEnum();
+                int cameraIndex = -1;
+                
+                for (int i = 0; i < cameraList.Count; i++)
+                {
+                    if (cameraList[i].Contains(SN))
+                    {
+                        cameraIndex = i;
+                        break;
+                    }
+                }
+                
+                if (cameraIndex == -1)
+                {
+                    throw new Exception($"鏈壘鍒板簭鍒楀彿涓� {SN} 鐨勭浉鏈�");
+                }
+                
+                // 鍒涘缓璁惧鍙ユ焺
+                int result = _camera.IMV_CreateHandle(IMVDefine.IMV_ECreateHandleMode.modeByIndex, cameraIndex);
+                if (result != IMVDefine.IMV_OK)
+                {
+                    throw new Exception($"鍒涘缓璁惧鍙ユ焺澶辫触锛岄敊璇爜锛歿result}");
+                }
+                
+                // 鎵撳紑璁惧
+                result = _camera.IMV_Open();
+                if (result != IMVDefine.IMV_OK)
+                {
+                    throw new Exception($"鎵撳紑鐩告満澶辫触锛岄敊璇爜锛歿result}");
+                }
+                
+                // 璁剧疆璁惧灞炴��
+                SN = SN;
+                isGrabbing = false;
+                
+                // 璁剧疆缂撳瓨涓暟涓�8
+                _camera.IMV_SetBufferCount(8);
+                
+                return true;
+            }
+            catch (Exception ex)
+            {
+                System.Diagnostics.Debug.WriteLine($"鍒濆鍖栫浉鏈哄け璐ワ細{ex.Message}");
+                return false;
+            }
+        }
+        
+        /// <summary>
+        /// 鍏抽棴鐩告満璁惧
+        /// </summary>
+        /// <returns>鍏抽棴鏄惁鎴愬姛</returns>
+        public override bool CloseDevice()
+        {
+            try
+            {
+                if (_camera == null)
+                    return true;
+                
+                // 鍋滄閲囬泦
+                if (_camera.IMV_IsGrabbing())
+                {
+                    StopGrabbing();
+                }
+                
+                // 鍏抽棴璁惧
+                if (_camera.IMV_IsOpen())
+                {
+                    int result = _camera.IMV_Close();
+                    if (result != IMVDefine.IMV_OK)
+                    {
+                        System.Diagnostics.Debug.WriteLine($"鍏抽棴鐩告満澶辫触锛岄敊璇爜锛歿result}");
+                    }
+                }
+                
+                // 閲婃斁璧勬簮
+                _isGrabbing = false;
+                isGrabbing = false;
+                
+                // 娓呯悊甯х紦瀛�
+                lock (_frameLock)
+                {
+                    foreach (var frame in _frameList)
+                    {
+                        var tempFrame = frame; // 鍒涘缓涓存椂鍙橀噺
+                        _camera.IMV_ReleaseFrame(ref tempFrame);
+                    }
+                    _frameList.Clear();
+                }
+                
+                return true;
+            }
+            catch (Exception ex)
+            {
+                System.Diagnostics.Debug.WriteLine($"鍏抽棴鐩告満澶辫触锛歿ex.Message}");
+                return false;
+            }
+        }
+        
+        #endregion
+
+        #region 鍥惧儚閲囬泦鎿嶄綔
+        
+        /// <summary>
+        /// 寮�濮嬪浘鍍忛噰闆�
+        /// </summary>
+        /// <returns>閲囬泦鍚姩鏄惁鎴愬姛</returns>
+        public override bool StartGrabbing()
+        {
+            try
+            {
+                if (_camera == null || !_camera.IMV_IsOpen())
+                {
+                    throw new Exception("鐩告満鏈墦寮�");
+                }
+                
+                // 鍋滄鐜版湁閲囬泦
+                if (_isGrabbing)
+                {
+                    StopGrabbing();
+                }
+                
+                // 鍚姩閲囬泦
+                int result = _camera.IMV_StartGrabbing();
+                if (result != IMVDefine.IMV_OK)
+                {
+                    throw new Exception($"鍚姩閲囬泦澶辫触锛岄敊璇爜锛歿result}");
+                }
+                
+                _isGrabbing = true;
+                isGrabbing = true;
+                
+                // 鍚姩閲囬泦绾跨▼
+                _threadRunning = true;
+                _grabThread = new Thread(GrabThreadProc);
+                _grabThread.IsBackground = true;
+                _grabThread.Start();
+                
+                return true;
+            }
+            catch (Exception ex)
+            {
+                System.Diagnostics.Debug.WriteLine($"鍚姩閲囬泦澶辫触锛歿ex.Message}");
+                _isGrabbing = false;
+                isGrabbing = false;
+                return false;
+            }
+        }
+        
+        /// <summary>
+        /// 鍋滄鍥惧儚閲囬泦
+        /// </summary>
+        /// <returns>鍋滄鏄惁鎴愬姛</returns>
+        public override bool StopGrabbing()
+        {
+            try
+            {
+                if (_camera == null || !_isGrabbing)
+                    return true;
+                
+                // 鍋滄绾跨▼
+                _threadRunning = false;
+                if (_grabThread != null && _grabThread.IsAlive)
+                {
+                    _grabThread.Join(1000);
+                    _grabThread = null;
+                }
+                
+                // 鍋滄閲囬泦
+                int result = _camera.IMV_StopGrabbing();
+                if (result != IMVDefine.IMV_OK)
+                {
+                    System.Diagnostics.Debug.WriteLine($"鍋滄閲囬泦澶辫触锛岄敊璇爜锛歿result}");
+                }
+                
+                _isGrabbing = false;
+                isGrabbing = false;
+                
+                // 娓呯悊缂撳瓨
+                lock (_frameLock)
+                {
+                    foreach (var frame in _frameList)
+                    {
+                        var tempFrame = frame; // 鍒涘缓涓存椂鍙橀噺
+                        _camera.IMV_ReleaseFrame(ref tempFrame);
+                    }
+                    _frameList.Clear();
+                }
+                
+                return true;
+            }
+            catch (Exception ex)
+            {
+                System.Diagnostics.Debug.WriteLine($"鍋滄閲囬泦澶辫触锛歿ex.Message}");
+                return false;
+            }
+        }
+        
+        /// <summary>
+        /// 鎵ц杞Е鍙�
+        /// </summary>
+        /// <returns>瑙﹀彂鏄惁鎴愬姛</returns>
+        public override bool SoftTrigger()
+        {
+            try
+            {
+                if (_camera == null || !_camera.IMV_IsOpen())
+                {
+                    throw new Exception("鐩告満鏈墦寮�");
+                }
+                
+                int result = _camera.IMV_ExecuteCommandFeature("TriggerSoftware");
+                return result == IMVDefine.IMV_OK;
+            }
+            catch (Exception ex)
+            {
+                System.Diagnostics.Debug.WriteLine($"杞Е鍙戝け璐ワ細{ex.Message}");
+                return false;
+            }
+        }
+        
+        #endregion
+
+        #region 鍙傛暟璁剧疆鍜岃幏鍙�
+        
+        /// <summary>
+        /// 璁剧疆瑙﹀彂妯″紡
+        /// </summary>
+        /// <param name="mode">瑙﹀彂妯″紡</param>
+        /// <param name="source">瑙﹀彂婧�</param>
+        /// <returns>璁剧疆鏄惁鎴愬姛</returns>
+        public override bool SetTriggerMode(TriggerMode mode, TriggerSource source = TriggerSource.Line0)
+        {
+            try
+            {
+                if (_camera == null || !_camera.IMV_IsOpen())
+                {
+                    throw new Exception("鐩告満鏈墦寮�");
+                }
+                
+                // 璁剧疆瑙﹀彂妯″紡
+                string triggerMode = mode == TriggerMode.On ? "On" : "Off";
+                int result = _camera.IMV_SetEnumFeatureSymbol("TriggerMode", triggerMode);
+                if (result != IMVDefine.IMV_OK)
+                {
+                    throw new Exception($"璁剧疆瑙﹀彂妯″紡澶辫触锛岄敊璇爜锛歿result}");
+                }
+                
+                // 璁剧疆瑙﹀彂婧�
+                if (mode == TriggerMode.On)
+                {
+                    string triggerSource = GetTriggerSourceString(source);
+                    result = _camera.IMV_SetEnumFeatureSymbol("TriggerSource", triggerSource);
+                    if (result != IMVDefine.IMV_OK)
+                    {
+                        throw new Exception($"璁剧疆瑙﹀彂婧愬け璐ワ紝閿欒鐮侊細{result}");
+                    }
+                }
+                
+                return true;
+            }
+            catch (Exception ex)
+            {
+                System.Diagnostics.Debug.WriteLine($"璁剧疆瑙﹀彂妯″紡澶辫触锛歿ex.Message}");
+                return false;
+            }
+        }
+        
+        /// <summary>
+        /// 鑾峰彇瑙﹀彂妯″紡
+        /// </summary>
+        /// <param name="mode">瑙﹀彂妯″紡</param>
+        /// <param name="source">瑙﹀彂婧�</param>
+        /// <returns>鑾峰彇鏄惁鎴愬姛</returns>
+        public override bool GetTriggerMode(out TriggerMode mode, out TriggerSource source)
+        {
+            mode = TriggerMode.Off;
+            source = TriggerSource.Software;
+            
+            try
+            {
+                if (_camera == null || !_camera.IMV_IsOpen())
+                {
+                    throw new Exception("鐩告満鏈墦寮�");
+                }
+                
+                // 鑾峰彇瑙﹀彂妯″紡
+                IMVDefine.IMV_String triggerMode = new IMVDefine.IMV_String();
+                int result = _camera.IMV_GetEnumFeatureSymbol("TriggerMode", ref triggerMode);
+                if (result == IMVDefine.IMV_OK)
+                {
+                    mode = triggerMode.str == "On" ? TriggerMode.On : TriggerMode.Off;
+                }
+                
+                // 鑾峰彇瑙﹀彂婧�
+                IMVDefine.IMV_String triggerSource = new IMVDefine.IMV_String();
+                result = _camera.IMV_GetEnumFeatureSymbol("TriggerSource", ref triggerSource);
+                if (result == IMVDefine.IMV_OK)
+                {
+                    source = GetTriggerSourceFromString(triggerSource.str);
+                }
+                
+                return true;
+            }
+            catch (Exception ex)
+            {
+                System.Diagnostics.Debug.WriteLine($"鑾峰彇瑙﹀彂妯″紡澶辫触锛歿ex.Message}");
+                return false;
+            }
+        }
+        
+        /// <summary>
+        /// 璁剧疆鏇濆厜鏃堕棿
+        /// </summary>
+        /// <param name="value">鏇濆厜鏃堕棿锛堝井绉掞級</param>
+        /// <returns>璁剧疆鏄惁鎴愬姛</returns>
+        public override bool SetExpouseTime(double value)
+        {
+            try
+            {
+                if (_camera == null || !_camera.IMV_IsOpen())
+                {
+                    throw new Exception("鐩告満鏈墦寮�");
+                }
+                
+                // 楠岃瘉鏇濆厜鏃堕棿鑼冨洿
+                double minExp = 0, maxExp = 0;
+                int result = _camera.IMV_GetDoubleFeatureMin("ExposureTime", ref minExp);
+                if (result != IMVDefine.IMV_OK)
+                {
+                    throw new Exception($"鑾峰彇鏇濆厜鏃堕棿鏈�灏忓�煎け璐ワ紝閿欒鐮侊細{result}");
+                }
+                
+                result = _camera.IMV_GetDoubleFeatureMax("ExposureTime", ref maxExp);
+                if (result != IMVDefine.IMV_OK)
+                {
+                    throw new Exception($"鑾峰彇鏇濆厜鏃堕棿鏈�澶у�煎け璐ワ紝閿欒鐮侊細{result}");
+                }
+                
+                if (value < minExp || value > maxExp)
+                {
+                    throw new Exception($"鏇濆厜鏃堕棿瓒呭嚭鑼冨洿锛屾湁鏁堣寖鍥达細{minExp} - {maxExp}");
+                }
+                
+                // 璁剧疆鏇濆厜鏃堕棿
+                result = _camera.IMV_SetDoubleFeatureValue("ExposureTime", value);
+                if (result != IMVDefine.IMV_OK)
+                {
+                    throw new Exception($"璁剧疆鏇濆厜鏃堕棿澶辫触锛岄敊璇爜锛歿result}");
+                }
+                
+                return true;
+            }
+            catch (Exception ex)
+            {
+                System.Diagnostics.Debug.WriteLine($"璁剧疆鏇濆厜鏃堕棿澶辫触锛歿ex.Message}");
+                return false;
+            }
+        }
+        
+        /// <summary>
+        /// 鑾峰彇鏇濆厜鏃堕棿
+        /// </summary>
+        /// <param name="value">鏇濆厜鏃堕棿</param>
+        /// <returns>鑾峰彇鏄惁鎴愬姛</returns>
+        public override bool GetExpouseTime(out double value)
+        {
+            value = 0;
+            
+            try
+            {
+                if (_camera == null || !_camera.IMV_IsOpen())
+                {
+                    throw new Exception("鐩告満鏈墦寮�");
+                }
+                
+                int result = _camera.IMV_GetDoubleFeatureValue("ExposureTime", ref value);
+                return result == IMVDefine.IMV_OK;
+            }
+            catch (Exception ex)
+            {
+                System.Diagnostics.Debug.WriteLine($"鑾峰彇鏇濆厜鏃堕棿澶辫触锛歿ex.Message}");
+                return false;
+            }
+        }
+        
+        /// <summary>
+        /// 璁剧疆澧炵泭
+        /// </summary>
+        /// <param name="gain">澧炵泭鍊�</param>
+        /// <returns>璁剧疆鏄惁鎴愬姛</returns>
+        public override bool SetGain(double gain)
+        {
+            try
+            {
+                if (_camera == null || !_camera.IMV_IsOpen())
+                {
+                    throw new Exception("鐩告満鏈墦寮�");
+                }
+                
+                // 楠岃瘉澧炵泭鑼冨洿
+                double minGain = 0, maxGain = 0;
+                int result = _camera.IMV_GetDoubleFeatureMin("GainRaw", ref minGain);
+                if (result != IMVDefine.IMV_OK)
+                {
+                    throw new Exception($"鑾峰彇澧炵泭鏈�灏忓�煎け璐ワ紝閿欒鐮侊細{result}");
+                }
+                
+                result = _camera.IMV_GetDoubleFeatureMax("GainRaw", ref maxGain);
+                if (result != IMVDefine.IMV_OK)
+                {
+                    throw new Exception($"鑾峰彇澧炵泭鏈�澶у�煎け璐ワ紝閿欒鐮侊細{result}");
+                }
+                
+                if (gain < minGain || gain > maxGain)
+                {
+                    throw new Exception($"澧炵泭鍊艰秴鍑鸿寖鍥达紝鏈夋晥鑼冨洿锛歿minGain} - {maxGain}");
+                }
+                
+                // 璁剧疆澧炵泭
+                result = _camera.IMV_SetDoubleFeatureValue("GainRaw", gain);
+                if (result != IMVDefine.IMV_OK)
+                {
+                    throw new Exception($"璁剧疆澧炵泭澶辫触锛岄敊璇爜锛歿result}");
+                }
+                
+                return true;
+            }
+            catch (Exception ex)
+            {
+                System.Diagnostics.Debug.WriteLine($"璁剧疆澧炵泭澶辫触锛歿ex.Message}");
+                return false;
+            }
+        }
+        
+        /// <summary>
+        /// 鑾峰彇澧炵泭鍊�
+        /// </summary>
+        /// <param name="gain">澧炵泭鍊�</param>
+        /// <returns>鑾峰彇鏄惁鎴愬姛</returns>
+        public override bool GetGain(out double gain)
+        {
+            gain = 0;
+            
+            try
+            {
+                if (_camera == null || !_camera.IMV_IsOpen())
+                {
+                    throw new Exception("鐩告満鏈墦寮�");
+                }
+                
+                int result = _camera.IMV_GetDoubleFeatureValue("GainRaw", ref gain);
+                return result == IMVDefine.IMV_OK;
+            }
+            catch (Exception ex)
+            {
+                System.Diagnostics.Debug.WriteLine($"鑾峰彇澧炵泭澶辫触锛歿ex.Message}");
+                return false;
+            }
+        }
+        
+        // 鍏朵粬鍙傛暟璁剧疆鏂规硶绫讳技锛岃繖閲岀渷鐣ラ儴鍒嗗疄鐜�...
+        
+        #endregion
+
+        #region 杈呭姪鏂规硶
+        
+        /// <summary>
+        /// 鍥惧儚閲囬泦绾跨▼澶勭悊鍑芥暟
+        /// </summary>
+        private void GrabThreadProc()
+        {
+            IMVDefine.IMV_Frame frame = new IMVDefine.IMV_Frame();
+            
+            while (_threadRunning)
+            {
+                try
+                {
+                    // 鑾峰彇鍥惧儚甯�
+                    int result = _camera.IMV_GetFrame(ref frame, 100);
+                    
+                    if (result == IMVDefine.IMV_OK)
+                    {
+                        // 澶勭悊鍥惧儚甯�
+                        ProcessFrame(frame);
+                    }
+                    else if (result != 0x80000001) // 瓒呮椂閿欒浠g爜锛堝父瑙佸�硷級
+                    {
+                        // 闈炶秴鏃堕敊璇�
+                        System.Diagnostics.Debug.WriteLine($"鑾峰彇鍥惧儚甯уけ璐ワ紝閿欒鐮侊細{result}");
+                    }
+                }
+                catch (Exception ex)
+                {
+                    System.Diagnostics.Debug.WriteLine($"閲囬泦绾跨▼寮傚父锛歿ex.Message}");
+                }
+                
+                Thread.Sleep(1);
+            }
+        }
+        
+        /// <summary>
+        /// 澶勭悊鍥惧儚甯�
+        /// </summary>
+        /// <param name="frame">鍥惧儚甯�</param>
+        private void ProcessFrame(IMVDefine.IMV_Frame frame)
+        {
+            try
+            {
+                // 灏嗗浘鍍忔暟鎹浆鎹负Bitmap
+                Bitmap bitmap = ConvertFrameToBitmap(frame);
+                
+                if (bitmap != null)
+                {
+                    // 瑙﹀彂鍥惧儚閲囬泦浜嬩欢
+                    CameraEventArgs args = new CameraEventArgs(SN, bitmap);
+                    ImageGrabbed?.Invoke(this, args);
+                    
+                    // 鏇存柊鍥炶皟鍥惧儚
+                    CallBackImg = bitmap;
+                }
+                
+                // 閲婃斁甯�
+                _camera.IMV_ReleaseFrame(ref frame);
+            }
+            catch (Exception ex)
+            {
+                System.Diagnostics.Debug.WriteLine($"澶勭悊鍥惧儚甯уけ璐ワ細{ex.Message}");
+            }
+        }
+        
+        /// <summary>
+        /// 灏嗗浘鍍忓抚杞崲涓築itmap
+        /// </summary>
+        /// <param name="frame">鍥惧儚甯�</param>
+        /// <returns>Bitmap瀵硅薄</returns>
+        private Bitmap ConvertFrameToBitmap(IMVDefine.IMV_Frame frame)
+        {
+            try
+            {
+                Bitmap bitmap = null;
+                
+                switch (frame.frameInfo.pixelFormat)
+                {
+                    case IMVDefine.IMV_EPixelType.gvspPixelMono8:
+                        bitmap = CreateMono8Bitmap(frame);
+                        break;
+                    case IMVDefine.IMV_EPixelType.gvspPixelBGR8:
+                        bitmap = CreateBgr8Bitmap(frame);
+                        break;
+                    default:
+                        // 鍏朵粬鏍煎紡闇�瑕佽浆鎹�
+                        bitmap = ConvertToBGR8(frame);
+                        break;
+                }
+                
+                return bitmap;
+            }
+            catch (Exception ex)
+            {
+                System.Diagnostics.Debug.WriteLine($"鍥惧儚鏍煎紡杞崲澶辫触锛歿ex.Message}");
+                return null;
+            }
+        }
+        
+        /// <summary>
+        /// 鍒涘缓Mono8鏍煎紡Bitmap
+        /// </summary>
+        private Bitmap CreateMono8Bitmap(IMVDefine.IMV_Frame frame)
+        {
+            Bitmap bitmap = new Bitmap((int)frame.frameInfo.width, (int)frame.frameInfo.height, PixelFormat.Format8bppIndexed);
+            
+            // 璁剧疆鐏板害璋冭壊鏉�
+            ColorPalette palette = bitmap.Palette;
+            for (int i = 0; i < 256; i++)
+            {
+                palette.Entries[i] = Color.FromArgb(i, i, i);
+            }
+            bitmap.Palette = palette;
+            
+            // 澶嶅埗鍥惧儚鏁版嵁
+            BitmapData bmpData = bitmap.LockBits(
+                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
+                ImageLockMode.WriteOnly,
+                bitmap.PixelFormat);
+            
+            // 浣跨敤CopyMemory API杩涜鍐呭瓨澶嶅埗
+            CopyMemory(bmpData.Scan0, frame.pData, (uint)Math.Min(frame.frameInfo.size, (uint)(bmpData.Stride * bitmap.Height)));
+            
+            bitmap.UnlockBits(bmpData);
+            return bitmap;
+        }
+        
+        /// <summary>
+        /// 鍒涘缓BGR8鏍煎紡Bitmap
+        /// </summary>
+        private Bitmap CreateBgr8Bitmap(IMVDefine.IMV_Frame frame)
+        {
+            Bitmap bitmap = new Bitmap((int)frame.frameInfo.width, (int)frame.frameInfo.height, PixelFormat.Format24bppRgb);
+            
+            BitmapData bmpData = bitmap.LockBits(
+                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
+                ImageLockMode.WriteOnly,
+                bitmap.PixelFormat);
+            
+            // 浣跨敤CopyMemory API杩涜鍐呭瓨澶嶅埗
+            CopyMemory(bmpData.Scan0, frame.pData, (uint)Math.Min(frame.frameInfo.size, (uint)(bmpData.Stride * bitmap.Height)));
+            
+            bitmap.UnlockBits(bmpData);
+            return bitmap;
+        }
+        
+        /// <summary>
+        /// 杞崲涓築GR8鏍煎紡
+        /// </summary>
+        private Bitmap ConvertToBGR8(IMVDefine.IMV_Frame frame)
+        {
+            IMVDefine.IMV_PixelConvertParam convertParam = new IMVDefine.IMV_PixelConvertParam
+            {
+                nWidth = frame.frameInfo.width,
+                nHeight = frame.frameInfo.height,
+                ePixelFormat = frame.frameInfo.pixelFormat,
+                pSrcData = frame.pData,
+                nSrcDataLen = frame.frameInfo.size,
+                nPaddingX = frame.frameInfo.paddingX,
+                nPaddingY = frame.frameInfo.paddingY,
+                eBayerDemosaic = IMVDefine.IMV_EBayerDemosaic.demosaicBilinear,
+                eDstPixelFormat = IMVDefine.IMV_EPixelType.gvspPixelBGR8,
+                nDstBufSize = frame.frameInfo.width * frame.frameInfo.height * 3
+            };
+            
+            IntPtr dstBuffer = Marshal.AllocHGlobal((int)convertParam.nDstBufSize);
+            convertParam.pDstBuf = dstBuffer;
+            
+            try
+            {
+                int result = _camera.IMV_PixelConvert(ref convertParam);
+                if (result == IMVDefine.IMV_OK)
+                {
+                    return CreateBgr8BitmapFromBuffer(dstBuffer, frame.frameInfo.width, frame.frameInfo.height);
+                }
+                return null;
+            }
+            finally
+            {
+                Marshal.FreeHGlobal(dstBuffer);
+            }
+        }
+        
+        /// <summary>
+        /// 浠庣紦鍐插尯鍒涘缓BGR8 Bitmap
+        /// </summary>
+        private Bitmap CreateBgr8BitmapFromBuffer(IntPtr buffer, uint width, uint height)
+        {
+            Bitmap bitmap = new Bitmap((int)width, (int)height, PixelFormat.Format24bppRgb);
+            
+            BitmapData bmpData = bitmap.LockBits(
+                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
+                ImageLockMode.WriteOnly,
+                bitmap.PixelFormat);
+            
+            // 浣跨敤CopyMemory API杩涜瀹夊叏鐨勫唴瀛樺鍒�
+            CopyMemory(bmpData.Scan0, buffer, (uint)(width * height * 3));
+            
+            bitmap.UnlockBits(bmpData);
+            return bitmap;
+        }
+        
+        /// <summary>
+        /// 灏嗚Е鍙戞簮鏋氫妇杞崲涓哄瓧绗︿覆
+        /// </summary>
+        private string GetTriggerSourceString(TriggerSource source)
+        {
+            return source switch
+            {
+                TriggerSource.Software => "Software",
+                TriggerSource.Line0 => "Line0",
+                TriggerSource.Line1 => "Line1",
+                TriggerSource.Line2 => "Line2",
+                TriggerSource.Line3 => "Line3",
+                TriggerSource.Line4 => "Line4",
+                TriggerSource.Line5 => "Line5",
+                _ => "Software"
+            };
+        }
+        
+        /// <summary>
+        /// 灏嗗瓧绗︿覆杞崲涓鸿Е鍙戞簮鏋氫妇
+        /// </summary>
+        private TriggerSource GetTriggerSourceFromString(string source)
+        {
+            return source switch
+            {
+                "Software" => TriggerSource.Software,
+                "Line0" => TriggerSource.Line0,
+                "Line1" => TriggerSource.Line1,
+                "Line2" => TriggerSource.Line2,
+                "Line3" => TriggerSource.Line3,
+                "Line4" => TriggerSource.Line4,
+                "Line5" => TriggerSource.Line5,
+                _ => TriggerSource.Software
+            };
+        }
+        
+        #endregion
+
+        #region 鏈疄鐜扮殑鎶借薄鏂规硶锛堢畝鍖栫増瀹炵幇锛�
+        
+        public override bool SetTriggerPolarity(TriggerPolarity polarity)
+        {
+            // 鍗庣澘鐩告満鍙兘涓嶆敮鎸佽鍔熻兘锛岃繑鍥炴垚鍔�
+            return true;
+        }
+        
+        public override bool GetTriggerPolarity(out TriggerPolarity polarity)
+        {
+            polarity = TriggerPolarity.RisingEdge;
+            return true;
+        }
+        
+        public override bool SetTriggerFliter(double flitertime)
+        {
+            // 鏆備笉鏀寔
+            return true;
+        }
+        
+        public override bool GetTriggerFliter(out double flitertime)
+        {
+            flitertime = 0;
+            return true;
+        }
+        
+        public override bool SetTriggerDelay(double delay)
+        {
+            // 鏆備笉鏀寔
+            return true;
+        }
+        
+        public override bool GetTriggerDelay(out double delay)
+        {
+            delay = 0;
+            return true;
+        }
+        
+        public override bool SetLineMode(IOLines line, LineMode mode)
+        {
+            // 鏆備笉鏀寔
+            return true;
+        }
+        
+        public override bool SetLineStatus(IOLines line, LineStatus linestatus)
+        {
+            // 鏆備笉鏀寔
+            return true;
+        }
+        
+        public override bool GetLineStatus(IOLines line, out LineStatus lineStatus)
+        {
+            lineStatus = LineStatus.Low;
+            return true;
+        }
+        
+        public override bool AutoBalanceWhite()
+        {
+            // 鏆備笉鏀寔鑷姩鐧藉钩琛�
+            return true;
+        }
+        
+        #endregion
+
+        #region IDisposable瀹炵幇
+        
+        private bool _disposed = false;
+        
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (disposing)
+                {
+                    // 閲婃斁鎵樼璧勬簮
+                }
+                
+                // 閲婃斁闈炴墭绠¤祫婧�
+                CloseDevice();
+                
+                _disposed = true;
+            }
+        }
+        
+        public override void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+        
+        #endregion
+    }
+}
\ No newline at end of file

--
Gitblit v1.9.3