Files
JoyD/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs
2025-10-29 14:47:34 +08:00

1299 lines
50 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace JoyD.Windows.CS.Toprie
{
public partial class Camera : UserControl
{
// 设备管理器实例
private DeviceManager _deviceManager;
// 是否正在接收图像
private bool _isReceivingImage = false;
// 显示错误的定时器
private System.Windows.Forms.Timer _errorDisplayTimer;
public Camera()
{
InitializeComponent();
// 为右键菜单添加Opening事件用于在菜单显示前更新色彩模式的选中状态
this.contextMenuStrip1.Opening += ContextMenuStrip1_Opening;
// 将设计模式状态传递给DeviceManager
DeviceManager.IsDesignMode = DesignMode;
// 只有在非设计模式下才初始化设备管理器和错误定时器
if (!DesignMode)
{
// 清空现有日志
try
{
string logFile = Path.Combine(Application.StartupPath, "log.txt");
if (File.Exists(logFile))
{
File.WriteAllText(logFile, string.Empty);
}
}
catch { }
InitializeDeviceManager();
InitializeErrorTimer();
}
}
/// <summary>
/// Camera控件加载事件
/// 在控件加载时自动启动相机显示热图
/// </summary>
private void Camera_Load(object sender, EventArgs e)
{
// 只有在非设计模式下才启动相机
if (!DesignMode)
{
try
{
StartCamera();
}
catch (Exception ex)
{
ShowError($"自动启动相机失败: {ex.Message}");
}
}
}
// 注意UserControl不支持FormClosing事件资源清理已在Dispose方法中处理
/// <summary>
/// 初始化设备管理器
/// </summary>
private void InitializeDeviceManager()
{
_deviceManager = new DeviceManager
{
AutoReconnectEnabled = true,
ReconnectInterval = 2000 // 2秒
};
// 确保DeviceManager的设计模式状态与控件一致
DeviceManager.IsDesignMode = DesignMode;
// 设置静态属性
DeviceManager.MaxReconnectAttempts = 5;
// 注册图像接收事件
_deviceManager.ImageReceived += DeviceManager_ImageReceived;
// 注册连接状态变更事件
_deviceManager.ConnectionStatusChanged += DeviceManager_ConnectionStatusChanged;
// 注册连接异常事件
_deviceManager.ConnectionException += DeviceManager_ConnectionException;
}
/// <summary>
/// 初始化错误显示定时器
/// </summary>
private void InitializeErrorTimer()
{
_errorDisplayTimer = new System.Windows.Forms.Timer { Interval = 3000 }; // 显示3秒后清除
_errorDisplayTimer.Tick += ErrorDisplayTimer_Tick;
}
/// <summary>
/// 启动相机
/// </summary>
public void StartCamera()
{
try
{
// 只有在没有接收图像时才启动
if (!_isReceivingImage)
{
// 清理错误显示
ShowError(string.Empty);
// 使用异步方式连接设备和设置模式避免UI线程阻塞
ThreadPool.QueueUserWorkItem(delegate
{
try
{
// 设置为热图模式
bool modeSet = false;
// 启用自动重连
_deviceManager.AutoReconnectEnabled = true;
// 尝试连接设备
if (_deviceManager.ConnectDevice())
{
Console.WriteLine("设备连接成功");
// 如果热图模式未成功设置,在连接成功后再次尝试
if (!modeSet)
{
try
{
_deviceManager.SetImageMode(ImageMode.Infrared);
Console.WriteLine("连接后已设置热图模式");
}
catch (Exception ex)
{
Console.WriteLine($"连接后设置热图模式失败: {ex.Message}");
}
}
// 在连接成功后开始接收图像
this.Invoke(new Action(() =>
{
// 再次检查是否已在UI线程设置为接收状态
if (!_isReceivingImage)
{
StartReceiveImage();
}
}));
}
else
{
// 连接失败时显示错误
string errorMsg = "设备连接失败,请检查设备状态或网络连接";
this.Invoke(new Action(() => ShowError(errorMsg)));
Console.WriteLine(errorMsg);
}
}
catch (Exception ex)
{
// 捕获所有异常,防止后台线程崩溃
string errorMsg = $"启动相机异常: {ex.Message}";
this.Invoke(new Action(() => ShowError(errorMsg)));
Console.WriteLine(errorMsg);
Console.WriteLine(ex.StackTrace);
}
});
Console.WriteLine("相机启动流程已开始");
}
else
{
Console.WriteLine("相机已在运行状态");
}
}
catch (Exception ex)
{
ShowError($"启动相机失败: {ex.Message}");
Console.WriteLine($"启动相机主流程错误: {ex.Message}");
Console.WriteLine(ex.StackTrace);
}
}
/// <summary>
/// 开始接收图像使用HTTP方式
/// </summary>
private void StartReceiveImage()
{
try
{
if (!_isReceivingImage && _deviceManager.ConnectionStatus == ConnectionStatus.Connected)
{
Console.WriteLine("Camera开始使用HTTP方式接收图像");
// 直接调用HTTP方式的图像接收
_deviceManager.StartImageReceiving();
_isReceivingImage = true;
}
}
catch (Exception ex)
{
ShowError($"开始接收图像失败: {ex.Message}");
}
}
/// <summary>
/// 停止接收图像
/// </summary>
public void StopCamera()
{
try
{
if (_isReceivingImage)
{
_deviceManager.StopReceiveImage();
_isReceivingImage = false;
}
}
catch (Exception ex)
{
Console.WriteLine($"停止相机失败: {ex.Message}");
}
}
/// <summary>
/// 设备管理器图像接收事件处理
/// </summary>
private void DeviceManager_ImageReceived(object sender, ImageReceivedEventArgs e)
{
Image image = null;
try
{
if (e.ImageData != null && e.ImageData.Length > 0)
{
// 创建内存流并从流中创建图像
using (MemoryStream ms = new MemoryStream(e.ImageData))
{
// 检查流是否可读且有效
if (ms.CanRead && ms.Length > 0)
{
// 从流中创建图像
using (Image tempImage = System.Drawing.Image.FromStream(ms))
{
// 创建一个全新的位图而不仅仅是克隆,确保数据完整性
image = new Bitmap(tempImage);
// 立即验证新创建的图像是否有效
try
{
// 访问Width和Height属性来验证图像是否有效
int width = image.Width;
int height = image.Height;
if (width <= 0 || height <= 0)
{
Console.WriteLine("创建的图像尺寸无效");
image.Dispose();
image = null;
}
}
catch (Exception)
{
Console.WriteLine("创建的图像无效");
image.Dispose();
image = null;
}
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"创建图像失败: {ex.Message}");
// 确保在异常情况下释放资源
if (image != null)
{
image.Dispose();
image = null;
}
}
if (image == null)
{
Console.WriteLine("接收到空或无效的图像数据");
return;
}
try
{
// 尝试创建图像的克隆以传递给UI线程
Image clonedImage = null;
try
{
clonedImage = (Image)image.Clone();
// 验证克隆的图像是否有效
if (clonedImage.Width <= 0 || clonedImage.Height <= 0)
{
Console.WriteLine("克隆的图像尺寸无效");
clonedImage.Dispose();
image.Dispose(); // 确保原始图像也被释放
return;
}
}
catch (Exception ex)
{
Console.WriteLine($"克隆图像失败: {ex.Message}");
image.Dispose(); // 确保原始图像被释放
return;
}
// 确保在UI线程上更新并且检查控件是否已被释放
if (!this.IsDisposed && !this.Disposing)
{
if (this.InvokeRequired)
{
try
{
// 创建本地副本以避免闭包问题
Image imageForUI = clonedImage;
clonedImage = null; // 防止在异步操作期间被修改
// 使用BeginInvoke在UI线程上更新图像避免可能的死锁问题
this.BeginInvoke(new Action(() =>
{
try
{
UpdateImageOnUI(imageForUI);
}
catch (Exception ex)
{
Console.WriteLine($"更新UI图像失败: {ex.Message}");
// 如果UI更新失败确保克隆的图像被释放
if (imageForUI != null)
{
try
{
imageForUI.Dispose();
}
catch {}
}
}
}));
}
catch (Exception)
{
// 异常情况下确保释放图像资源
if (clonedImage != null)
{
try
{
clonedImage.Dispose();
}
catch {}
clonedImage = null;
}
throw;
}
}
else
{
// 在UI线程上直接更新图像
UpdateImageOnUI(clonedImage);
}
}
else
{
// 如果控件已释放,确保释放图像资源
clonedImage.Dispose();
}
// 释放原始图像资源
image.Dispose();
}
catch (Exception ex)
{
Console.WriteLine($"处理图像接收事件失败: {ex.Message}");
// 确保在任何异常情况下都释放原始图像
if (image != null)
{
try
{
image.Dispose();
}
catch {}
}
}
}
/// <summary>
/// 在UI线程上更新图像
/// </summary>
private void UpdateImageOnUI(Image image)
{
// 线程安全检查 - 确保在UI线程上执行
if (this.InvokeRequired)
{
try
{
this.BeginInvoke(new Action<Image>(UpdateImageOnUI), image);
}
catch (ObjectDisposedException)
{
// 如果控件已被释放,确保释放图像资源
if (image != null)
{
try { image.Dispose(); } catch {}
}
Console.WriteLine("控件已释放跳过UI更新");
}
return;
}
// 空值检查
if (image == null)
{
Console.WriteLine("传入UpdateImageOnUI的图像为空");
return;
}
// 连接状态检查 - 只在设备实际连接时处理图像
if (_deviceManager.ConnectionStatus != ConnectionStatus.Connected)
{
Console.WriteLine("设备未连接,跳过图像更新");
try { image.Dispose(); } catch {}
return;
}
// 增强图像有效性检查
bool isImageValid = false;
Image safeImage = null;
try
{
// 创建一个安全的图像副本,确保原图像不被破坏
safeImage = new Bitmap(image);
// 预先验证图像是否有效
if (safeImage.Width > 0 && safeImage.Height > 0)
{
// 尝试访问图像的像素数据,这是更严格的验证方式
using (Graphics g = Graphics.FromImage(new Bitmap(1, 1)))
{
// 简单绘制操作验证图像是否可绘制
g.DrawImage(safeImage, 0, 0, 1, 1);
}
isImageValid = true;
Console.WriteLine($"图像验证成功: {safeImage.Width}x{safeImage.Height}");
}
else
{
Console.WriteLine($"图像尺寸无效: {safeImage.Width}x{safeImage.Height}");
}
}
catch (Exception ex)
{
Console.WriteLine($"图像验证失败: {ex.Message}");
// 释放临时创建的安全图像
if (safeImage != null)
{
try { safeImage.Dispose(); } catch {}
}
// 释放原始图像
try { image.Dispose(); } catch {}
return;
}
try
{
// 更新图像前先检查控件是否存在/已释放
if (this.IsDisposed || imageBox == null || imageBox.IsDisposed)
{
// 如果控件已释放,确保图像也被释放
try { safeImage.Dispose(); } catch {}
try { image.Dispose(); } catch {}
Console.WriteLine("控件已释放,无法更新图像");
return;
}
// 保存旧图像引用,以便在设置新图像后释放
Image oldImage = imageBox.Image;
try
{
// 确保控件仍处于有效状态
if (imageBox.IsDisposed || !isImageValid || safeImage == null)
{
try { safeImage.Dispose(); } catch {}
try { image.Dispose(); } catch {}
return;
}
// 尝试设置新图像(使用验证过的安全副本)
imageBox.Image = safeImage;
// 验证图像是否成功设置
if (imageBox.Image != safeImage)
{
Console.WriteLine("图像设置失败,可能参数无效");
try { safeImage.Dispose(); } catch {}
try { image.Dispose(); } catch {}
return;
}
// 释放原始图像,因为我们现在使用的是安全副本
try { image.Dispose(); } catch {}
// 仅在新图像成功设置后释放旧图像
if (oldImage != null && oldImage != safeImage) // 防止自引用释放
{
try
{
oldImage.Dispose();
}
catch {}
}
}
catch (ArgumentException ex) when (ex.Message.Contains("参数无效"))
{
// 特别处理"参数无效"异常
Console.WriteLine($"图像参数无效异常: {ex.Message}");
try { safeImage.Dispose(); } catch {}
try { image.Dispose(); } catch {}
// 尝试设置旧图像回来,如果可能的话
if (oldImage != null)
{
try
{
imageBox.Image = oldImage;
}
catch
{
// 如果设置旧图像也失败,释放它
try { oldImage.Dispose(); } catch {}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"更新图像UI异常: {ex.Message}");
// 确保在任何异常情况下都释放所有图像资源
try { safeImage.Dispose(); } catch {}
try { image.Dispose(); } catch {}
}
}
/// <summary>
/// 设备管理器连接状态变更事件处理
/// </summary>
private void DeviceManager_ConnectionStatusChanged(object sender, ConnectionStatusChangedEventArgs e)
{
// 参数验证
if (e == null)
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 警告: 接收到空的连接状态变更事件参数");
return;
}
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] 接收连接状态变更事件: {e.Status}");
// 捕获所有可能的异常,确保事件处理器不会崩溃
try
{
// 首先检查控件状态
if (this.IsDisposed || this.Disposing)
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 控件已释放或正在释放跳过UI更新");
return;
}
// 检查事件参数中的状态信息
string statusMessage = $"连接状态变更为: {e.Status}";
if (!string.IsNullOrEmpty(e.DeviceInfo))
{
statusMessage += $" (设备信息: {e.DeviceInfo})";
}
// 线程安全处理 - 确保在UI线程上更新
if (this.InvokeRequired)
{
try
{
// 使用BeginInvoke代替Invoke避免可能的死锁问题
this.BeginInvoke(new Action<ConnectionStatusChangedEventArgs>(args =>
{
// 再次检查控件状态,防止在异步调用期间控件被释放
if (!this.IsDisposed && !this.Disposing)
{
HandleConnectionStatusChanged(args);
}
else
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 异步调用期间控件已释放,跳过处理");
}
}), e);
}
catch (ObjectDisposedException ode)
{
// 捕获控件已释放异常,避免程序崩溃
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 控件已释放无法进行UI线程调用: {ode.Message}");
}
catch (InvalidOperationException ioe)
{
// 捕获无效操作异常,通常发生在控件状态异常时
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] UI线程调用无效: {ioe.Message}");
}
}
else
{
// 直接在UI线程上处理
HandleConnectionStatusChanged(e);
}
}
catch (Exception ex)
{
// 捕获所有其他异常,记录并继续
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 处理连接状态变更事件异常: {ex.Message}\n{ex.StackTrace}");
}
}
/// <summary>
/// 处理连接状态变更
/// </summary>
private void HandleConnectionStatusChanged(ConnectionStatusChangedEventArgs e)
{
try
{
// 确保在UI线程上更新UI状态
if (this.InvokeRequired)
{
this.Invoke(new Action<ConnectionStatusChangedEventArgs>(HandleConnectionStatusChanged), e);
return;
}
// 更新UI状态
UpdateUIState(e.Status == ConnectionStatus.Connected);
// 检查_deviceManager是否为空
if (_deviceManager == null)
{
Console.WriteLine("设备管理器未初始化");
return;
}
switch (e.Status)
{
case ConnectionStatus.Connected:
Console.WriteLine("设备已连接");
// 清除错误信息
ShowError(string.Empty);
// 仅在首次连接时设置为热图模式,重连时保留之前的模式
if (!_isReceivingImage) // 首次连接时_isReceivingImage为false
{
try
{
_deviceManager.SetImageMode(ImageMode.Infrared);
Console.WriteLine("首次连接,设置热图模式");
}
catch (Exception ex)
{
Console.WriteLine($"设置热图模式失败: {ex.Message}");
}
}
else
{
Console.WriteLine("重连成功,保留当前图像模式");
}
// 注意色彩模式同步现在在DeviceManager内部的连接成功处理中自动完成
// 无需在此处重复调用
// 开始接收图像包含在try-catch中
if (!_isReceivingImage)
{
StartReceiveImage();
}
break;
case ConnectionStatus.Disconnected:
Console.WriteLine("设备已断开连接");
// 停止接收图像(添加空检查和异常处理)
if (_isReceivingImage)
{
try
{
_deviceManager.StopReceiveImage();
_isReceivingImage = false;
}
catch (Exception ex)
{
Console.WriteLine($"停止接收图像失败: {ex.Message}");
_isReceivingImage = false; // 确保状态更新
}
}
if (!string.IsNullOrEmpty(e.DeviceInfo))
{
ShowError(e.DeviceInfo);
}
else
{
ShowError("设备连接已断开");
}
break;
case ConnectionStatus.Connecting:
case ConnectionStatus.Reconnecting:
Console.WriteLine($"正在连接设备...{(!string.IsNullOrEmpty(e.DeviceInfo) ? " " + e.DeviceInfo : "")}");
ShowError(string.Empty); // 清除之前的错误信息
break;
}
}
catch (Exception ex)
{
Console.WriteLine($"处理连接状态变更时发生错误: {ex.Message}");
// 避免在异常处理中再次引起异常
try
{
ShowError($"连接状态处理错误: {ex.Message}");
}
catch
{}
}
}
/// <summary>
/// 更新UI状态
/// </summary>
/// <param name="isConnected">是否已连接</param>
private void UpdateUIState(bool isConnected)
{
try
{
// 根据连接状态更新图像框状态
if (imageBox != null && !imageBox.IsDisposed)
{
if (isConnected)
{
imageBox.BorderStyle = BorderStyle.FixedSingle;
}
else
{
imageBox.BorderStyle = BorderStyle.Fixed3D;
}
}
// 更新图像框的边框颜色,提供视觉反馈
if (imageBox != null)
{
imageBox.BorderStyle = isConnected ? BorderStyle.FixedSingle : BorderStyle.Fixed3D;
// 可选:设置不同的边框颜色以提供更好的视觉反馈
if (isConnected)
{
imageBox.BackColor = Color.LightGreen;
}
else
{
imageBox.BackColor = Color.LightGray;
}
}
Console.WriteLine($"UI状态已更新为: {(isConnected ? "" : "")}");
}
catch (Exception ex)
{
Console.WriteLine($"更新UI状态时出错: {ex.Message}");
}
}
/// <summary>
/// 设备管理器连接异常事件处理
/// </summary>
private void DeviceManager_ConnectionException(object sender, ConnectionExceptionEventArgs e)
{
// 参数验证
if (e == null)
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 警告: 接收到空的连接异常事件参数");
return;
}
// 记录详细的异常信息但避免在UI线程上执行耗时操作
string exceptionMessage = e.Exception != null ? e.Exception.Message : "无详细异常信息";
string stackTrace = e.Exception != null ? e.Exception.StackTrace : "无堆栈信息";
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] 接收连接异常事件: {e.Message}\n{exceptionMessage}\n{stackTrace}");
// 捕获所有可能的异常,确保异常处理不会导致程序崩溃
try
{
// 首先检查控件状态
if (this.IsDisposed || this.Disposing)
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 控件已释放或正在释放,跳过异常显示");
return;
}
// 创建用于UI显示的错误消息
string uiErrorMessage = $"连接异常: {e.Message}";
if (string.IsNullOrEmpty(e.Message) && e.Exception != null)
{
uiErrorMessage = $"连接异常: {exceptionMessage}";
}
// 线程安全处理 - 确保在UI线程上更新
if (this.InvokeRequired)
{
try
{
// 创建局部变量保存错误消息,避免闭包问题
string errorMsg = uiErrorMessage;
// 使用BeginInvoke代替Invoke避免可能的死锁问题
this.BeginInvoke(new Action(() =>
{
// 再次检查控件状态,防止在异步调用期间控件被释放
if (!this.IsDisposed && !this.Disposing)
{
try
{
ShowError(errorMsg);
}
catch (Exception showEx)
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 显示错误消息异常: {showEx.Message}");
}
}
else
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 异步调用期间控件已释放,跳过错误显示");
}
}));
}
catch (ObjectDisposedException ode)
{
// 捕获控件已释放异常,避免程序崩溃
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 控件已释放无法进行UI线程调用: {ode.Message}");
}
catch (InvalidOperationException ioe)
{
// 捕获无效操作异常,通常发生在控件状态异常时
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] UI线程调用无效: {ioe.Message}");
}
}
else
{
// 直接在UI线程上处理
try
{
ShowError(uiErrorMessage);
}
catch (Exception showEx)
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 显示错误消息异常: {showEx.Message}");
}
}
}
catch (Exception ex)
{
// 捕获所有其他异常,记录并继续
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 处理连接异常事件异常: {ex.Message}\n{ex.StackTrace}");
}
}
/// <summary>
/// 显示错误信息
/// </summary>
private void ShowError(string message)
{
Console.WriteLine(message);
// 可以根据需要添加UI上的错误显示
// 这里简化处理,只在控制台输出
// 检查imageBox是否存在且尺寸有效
if (imageBox == null || imageBox.Width <= 0 || imageBox.Height <= 0)
{
Console.WriteLine("imageBox尺寸无效跳过错误显示图像创建");
return;
}
// 确保使用有效的尺寸创建Bitmap
int width = Math.Max(100, imageBox.Width);
int height = Math.Max(100, imageBox.Height);
// 如果需要在图像区域显示错误文字,可以使用以下代码
using (Bitmap errorBitmap = new Bitmap(width, height))
using (Graphics g = Graphics.FromImage(errorBitmap))
{
g.Clear(Color.Black);
using (Font font = new Font("Arial", 10))
using (Brush brush = new SolidBrush(Color.Red))
{
SizeF textSize = g.MeasureString(message, font);
PointF textLocation = new PointF(
(errorBitmap.Width - textSize.Width) / 2,
(errorBitmap.Height - textSize.Height) / 2);
g.DrawString(message, font, brush, textLocation);
}
UpdateImageOnUI(errorBitmap);
}
// 启动定时器3秒后清除错误显示
_errorDisplayTimer.Stop();
_errorDisplayTimer.Start();
}
/// <summary>
/// 错误显示定时器事件
/// </summary>
private void ErrorDisplayTimer_Tick(object sender, EventArgs e)
{
_errorDisplayTimer.Stop();
// 清除错误显示,恢复到等待图像状态
// 检查imageBox是否存在且尺寸有效
if (imageBox == null || imageBox.Width <= 0 || imageBox.Height <= 0)
{
Console.WriteLine("imageBox尺寸无效跳过等待图像创建");
return;
}
// 确保使用有效的尺寸创建Bitmap
int width = Math.Max(100, imageBox.Width);
int height = Math.Max(100, imageBox.Height);
using (Bitmap waitingBitmap = new Bitmap(width, height))
using (Graphics g = Graphics.FromImage(waitingBitmap))
{
g.Clear(Color.Black);
using (Font font = new Font("Arial", 10))
using (Brush brush = new SolidBrush(Color.White))
{
string waitingText = "正在等待热图数据...";
SizeF textSize = g.MeasureString(waitingText, font);
PointF textLocation = new PointF(
(waitingBitmap.Width - textSize.Width) / 2,
(waitingBitmap.Height - textSize.Height) / 2);
g.DrawString(waitingText, font, brush, textLocation);
}
UpdateImageOnUI(waitingBitmap);
}
}
/// <summary>
/// 右键菜单显示前的事件处理方法
/// 用于更新色彩模式菜单项的选中状态
/// </summary>
private void ContextMenuStrip1_Opening(object sender, System.ComponentModel.CancelEventArgs e)
{
try
{
// 清除视频模式菜单项的选中状态
thermalModeToolStripMenuItem.Checked = false;
visibleModeToolStripMenuItem.Checked = false;
fusionMode1ToolStripMenuItem.Checked = false;
fusionMode2ToolStripMenuItem.Checked = false;
fusionMode3ToolStripMenuItem.Checked = false;
fusionMode4ToolStripMenuItem.Checked = false;
fusionMode5ToolStripMenuItem.Checked = false;
// 清除色彩模式菜单项的选中状态
whiteHotToolStripMenuItem.Checked = false;
blackHotToolStripMenuItem.Checked = false;
ironRedToolStripMenuItem.Checked = false;
lavaToolStripMenuItem.Checked = false;
rainbowToolStripMenuItem.Checked = false;
ironGrayToolStripMenuItem.Checked = false;
redHotToolStripMenuItem.Checked = false;
rainbow2ToolStripMenuItem.Checked = false;
// 尝试获取当前色彩模式并更新对应菜单项的选中状态
if (_deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Connected)
{
try
{
// 获取当前色彩模式
PaletteType currentPalette = _deviceManager.CurrentPaletteType;
// 根据当前色彩模式设置对应菜单项的选中状态
switch (currentPalette)
{
case PaletteType.WhiteHot:
whiteHotToolStripMenuItem.Checked = true;
break;
case PaletteType.BlackHot:
blackHotToolStripMenuItem.Checked = true;
break;
case PaletteType.IronRed:
ironRedToolStripMenuItem.Checked = true;
break;
case PaletteType.Lava:
lavaToolStripMenuItem.Checked = true;
break;
case PaletteType.Rainbow:
rainbowToolStripMenuItem.Checked = true;
break;
case PaletteType.IronGray:
ironGrayToolStripMenuItem.Checked = true;
break;
case PaletteType.RedHot:
redHotToolStripMenuItem.Checked = true;
break;
case PaletteType.Rainbow2:
rainbow2ToolStripMenuItem.Checked = true;
break;
}
}
catch (Exception ex)
{
Console.WriteLine("获取当前色彩模式失败: " + ex.Message);
}
// 更新视频模式菜单项的选中状态
try
{
// 更改为使用ImageMode枚举
var currentImageMode = _deviceManager.CurrentImageMode;
thermalModeToolStripMenuItem.Checked = currentImageMode == ImageMode.Infrared;
visibleModeToolStripMenuItem.Checked = currentImageMode == ImageMode.Natural;
}
catch (Exception ex)
{
Console.WriteLine("获取当前图像模式失败: " + ex.Message);
}
}
}
catch (Exception ex)
{
Console.WriteLine("更新右键菜单选中状态失败: " + ex.Message);
}
}
#region
/// <summary>
/// 白热色彩模式
/// </summary>
private void whiteHotToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
if (_deviceManager != null)
{
Console.WriteLine("切换到白热色彩模式");
_deviceManager.SetPaletteType(PaletteType.WhiteHot);
}
}
catch (Exception ex)
{
Console.WriteLine($"切换到白热色彩模式失败: {ex.Message}");
}
}
/// <summary>
/// 黑热色彩模式
/// </summary>
private void blackHotToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
if (_deviceManager != null)
{
Console.WriteLine("切换到黑热色彩模式");
_deviceManager.SetPaletteType(PaletteType.BlackHot);
}
}
catch (Exception ex)
{
Console.WriteLine($"切换到黑热色彩模式失败: {ex.Message}");
}
}
/// <summary>
/// 铁红色彩模式
/// </summary>
private void ironRedToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
if (_deviceManager != null)
{
Console.WriteLine("切换到铁红色彩模式");
_deviceManager.SetPaletteType(PaletteType.IronRed);
}
}
catch (Exception ex)
{
Console.WriteLine($"切换到铁红色彩模式失败: {ex.Message}");
}
}
/// <summary>
/// 熔岩色彩模式
/// </summary>
private void lavaToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
if (_deviceManager != null)
{
Console.WriteLine("切换到熔岩色彩模式");
_deviceManager.SetPaletteType(PaletteType.Lava);
}
}
catch (Exception ex)
{
Console.WriteLine($"切换到熔岩色彩模式失败: {ex.Message}");
}
}
/// <summary>
/// 彩虹色彩模式
/// </summary>
private void rainbowToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
if (_deviceManager != null)
{
Console.WriteLine("切换到彩虹色彩模式");
_deviceManager.SetPaletteType(PaletteType.Rainbow);
}
}
catch (Exception ex)
{
Console.WriteLine($"切换到彩虹色彩模式失败: {ex.Message}");
}
}
/// <summary>
/// 铁灰色彩模式
/// </summary>
private void ironGrayToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
if (_deviceManager != null)
{
Console.WriteLine("切换到铁灰色彩模式");
_deviceManager.SetPaletteType(PaletteType.IronGray);
}
}
catch (Exception ex)
{
Console.WriteLine($"切换到铁灰色彩模式失败: {ex.Message}");
}
}
/// <summary>
/// 红热色彩模式
/// </summary>
private void redHotToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
if (_deviceManager != null)
{
Console.WriteLine("切换到红热色彩模式");
_deviceManager.SetPaletteType(PaletteType.RedHot);
}
}
catch (Exception ex)
{
Console.WriteLine($"切换到红热色彩模式失败: {ex.Message}");
}
}
/// <summary>
/// 彩虹2色彩模式
/// </summary>
private void rainbow2ToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
if (_deviceManager != null)
{
Console.WriteLine("切换到彩虹2色彩模式");
_deviceManager.SetPaletteType(PaletteType.Rainbow2);
}
}
catch (Exception ex)
{
Console.WriteLine($"切换到彩虹2色彩模式失败: {ex.Message}");
}
}
#endregion
#region
/// <summary>
/// 红外模式
/// </summary>
private void thermalModeToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_deviceManager.SetImageMode(ImageMode.Infrared);
}
catch (Exception ex)
{
Console.WriteLine("切换到红外模式失败: " + ex.Message);
ShowError("切换到红外模式失败");
}
}
private void visibleModeToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_deviceManager.SetImageMode(ImageMode.Natural);
}
catch (Exception ex)
{
Console.WriteLine("切换到自然模式失败: " + ex.Message);
ShowError("切换到自然模式失败");
}
}
#endregion
/// <summary>
/// 清理资源
/// </summary>
protected override void Dispose(bool disposing)
{
if (disposing)
{
// 检查是否处于设计模式
if (!DesignMode)
{
// 停止相机并释放相关资源
try
{
StopCamera();
}
catch (Exception ex)
{
Console.WriteLine("关闭相机时出错: " + ex.Message);
}
}
// 取消注册事件并释放设备管理器
if (_deviceManager != null)
{
// 移除所有事件监听
_deviceManager.ImageReceived -= DeviceManager_ImageReceived;
_deviceManager.ConnectionStatusChanged -= DeviceManager_ConnectionStatusChanged;
_deviceManager.ConnectionException -= DeviceManager_ConnectionException;
// 释放设备管理器资源
_deviceManager.Dispose();
_deviceManager = null;
}
// 无论是否在设计模式下,都需要释放定时器
if (_errorDisplayTimer != null)
{
_errorDisplayTimer.Stop();
_errorDisplayTimer.Dispose();
_errorDisplayTimer = null;
}
// 无论是否在设计模式下,都需要释放图像资源
if (imageBox != null && !imageBox.IsDisposed && imageBox.Image != null)
{
imageBox.Image.Dispose();
imageBox.Image = null;
}
// 释放组件资源
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
}
}