优化图像更新流程:使用_isPaused标志管理暂停状态,统一Info显示逻辑,实现完整的三步绘制流程

This commit is contained in:
zqm
2025-10-30 11:05:08 +08:00
parent 58705feec5
commit 27a95aa239

View File

@@ -78,8 +78,96 @@ namespace JoyD.Windows.CS.Toprie
Console.WriteLine($"相机控件设计模式状态已更新: {DesignMode}"); Console.WriteLine($"相机控件设计模式状态已更新: {DesignMode}");
} }
/// <summary>
/// 更新InfoImage显示
/// 1. 如果断开,显示重连信息
/// 2. 否则如果暂停,显示暂停信息
/// 3. 最后调用更新UI
/// </summary>
private void UpdateInfo()
{
if (DesignMode) return;
try
{
lock (_infoImageLock)
{
// 释放之前的InfoImage资源
if (_infoImage != null)
{
try
{
_infoImage.Dispose();
}
catch (Exception ex)
{
Console.WriteLine($"释放InfoImage资源异常: {ex.Message}");
}
_infoImage = null;
}
// 检查连接状态
bool isDisconnected = _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Disconnected;
bool isReconnecting = _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Reconnecting;
bool isPaused = _isPaused; // 使用_isPaused标志判断暂停状态
// 如果需要显示信息创建InfoImage
if (isDisconnected || isReconnecting || isPaused)
{
_infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT);
using (Graphics g = Graphics.FromImage(_infoImage))
{
// 设置半透明背景
using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Black)))
{
g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT);
}
// 确定显示的文本和颜色
string text = "";
Color textColor = Color.White;
if (isDisconnected || isReconnecting)
{
// 断开或重连状态
text = isReconnecting ? "正在重连..." : "连接断开";
textColor = isReconnecting ? Color.Yellow : Color.Red;
}
else if (isPaused)
{
// 暂停状态
text = "暂停";
textColor = Color.Red;
}
// 绘制文本
using (Font font = new Font("Arial", 48, FontStyle.Bold))
using (SolidBrush textBrush = new SolidBrush(textColor))
{
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
g.DrawString(text, font, textBrush, new RectangleF(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format);
}
}
}
// 设置显示标志
_isDisplayingInfo = (isDisconnected || isReconnecting || isPaused);
}
// 调用更新UI
UpdateImageOnUI();
}
catch (Exception ex)
{
Console.WriteLine($"更新Info显示时出错: {ex.Message}");
}
}
/// <summary> /// <summary>
/// 暂停/恢复图像更新菜单项点击事件处理 /// 暂停/恢复图像更新菜单项点击事件处理
/// 1、暂停或恢复时设置暂停状态调用更新Info
/// </summary> /// </summary>
private void PauseImageUpdateToolStripMenuItem_Click(object sender, EventArgs e) private void PauseImageUpdateToolStripMenuItem_Click(object sender, EventArgs e)
{ {
@@ -87,94 +175,47 @@ namespace JoyD.Windows.CS.Toprie
try try
{ {
bool isPaused = pauseImageUpdateToolStripMenuItem.Text == "暂停图像更新"; // 切换暂停状态
_isPaused = !_isPaused;
if (isPaused) if (_isPaused)
{ {
// 设置暂停状态
pauseImageUpdateToolStripMenuItem.Text = "恢复图像更新"; pauseImageUpdateToolStripMenuItem.Text = "恢复图像更新";
Console.WriteLine("图像更新已暂停");
// 在InfoImage中绘制暂停字样 // 暂停时停止图像接收
lock (_infoImageLock)
{
// 释放之前的InfoImage资源
if (_infoImage != null)
{
try
{
_infoImage.Dispose();
}
catch (Exception ex)
{
Console.WriteLine($"释放InfoImage资源异常: {ex.Message}");
}
}
// 创建新的InfoImage并绘制暂停字样
_infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT);
using (Graphics g = Graphics.FromImage(_infoImage))
{
// 设置半透明背景
using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Black)))
{
g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT);
}
// 绘制暂停字样
using (Font font = new Font("Arial", 48, FontStyle.Bold))
using (SolidBrush textBrush = new SolidBrush(Color.Red))
{
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
g.DrawString("暂停", font, textBrush, new RectangleF(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format);
}
}
}
// 设置显示信息标志并更新UI
_isDisplayingInfo = true;
UpdateImageOnUI();
}
else
{
pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新";
Console.WriteLine("图像更新已恢复");
// 清除InfoImage和显示标志
lock (_infoImageLock)
{
if (_infoImage != null)
{
try
{
_infoImage.Dispose();
_infoImage = null;
}
catch (Exception ex)
{
Console.WriteLine($"释放InfoImage资源异常: {ex.Message}");
}
}
}
_isDisplayingInfo = false;
// 立即更新UI
UpdateImageOnUI();
// 恢复时,立即停止并重新开始图像接收,确保获取最新图像
if (_isReceivingImage && _deviceManager != null) if (_isReceivingImage && _deviceManager != null)
{ {
_deviceManager.StopImageReceiving(); _deviceManager.StopImageReceiving();
_deviceManager.StartImageReceiving(); _isReceivingImage = false;
} }
Console.WriteLine("图像更新已暂停");
} }
else
{
// 设置恢复状态
pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新";
// 恢复时,立即停止并重新开始图像接收,确保获取最新图像
if (_deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Connected)
{
_deviceManager.StopImageReceiving();
_deviceManager.StartImageReceiving();
_isReceivingImage = true;
}
Console.WriteLine("图像更新已恢复");
}
// 按照用户要求暂停或恢复时设置暂停状态调用更新Info
UpdateInfo();
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine($"处理暂停/恢复图像更新时出错: {ex.Message}"); Console.WriteLine($"处理暂停/恢复图像更新时出错: {ex.Message}");
} }
} }
public Camera() public Camera()
{ {
@@ -428,84 +469,86 @@ namespace JoyD.Windows.CS.Toprie
} }
} }
private bool _isPaused = false; // 暂停状态标志
/// <summary> /// <summary>
/// 设备管理器图像接收事件处理 /// 设备管理器图像接收事件处理
/// </summary> /// </summary>
private void DeviceManager_ImageReceived(object sender, ImageReceivedEventArgs e) private void DeviceManager_ImageReceived(object sender, ImageReceivedEventArgs e)
{ {
// 如果图像更新已暂停则不更新UI
// 通过菜单项文本判断是否暂停
if (pauseImageUpdateToolStripMenuItem.Text == "恢复图像更新")
return;
if (DesignMode) return; if (DesignMode) return;
try try
{ {
if (e.ImageData != null && e.ImageData.Length > 0) if (e.ImageData != null && e.ImageData.Length > 0)
{ {
// 创建内存流并从流中创建图像 // 创建内存流并从流中创建图像
using (MemoryStream ms = new MemoryStream(e.ImageData)) using (MemoryStream ms = new MemoryStream(e.ImageData))
{ {
// 检查流是否可读且有效 // 检查流是否可读且有效
if (ms.CanRead && ms.Length > 0) if (ms.CanRead && ms.Length > 0)
{ {
// 从流中创建图像 // 从流中创建图像
using (Image tempImage = System.Drawing.Image.FromStream(ms)) using (Image tempImage = System.Drawing.Image.FromStream(ms))
{ {
// 创建一个全新的位图而仅仅是克隆,确保数据完整性 // 创建一个全新的位图而仅仅是克隆,确保数据完整性
Image newImage = new Bitmap(tempImage); Image newImage = new Bitmap(tempImage);
// 立即验证新创建的图像是否有效 // 立即验证新创建的图像是否有效
try try
{ {
// 访问Width和Height属性来验证图像是否有效 // 访问Width和Height属性来验证图像是否有效
int width = newImage.Width; int width = newImage.Width;
int height = newImage.Height; int height = newImage.Height;
if (width <= 0 || height <= 0) if (width <= 0 || height <= 0)
{ {
Console.WriteLine("创建的图像尺寸无效"); Console.WriteLine("创建的图像尺寸无效");
newImage.Dispose(); newImage.Dispose();
return; return;
} }
} }
catch (Exception) catch (Exception)
{ {
Console.WriteLine("创建的图像无效"); Console.WriteLine("创建的图像无效");
newImage.Dispose(); newImage.Dispose();
return; return;
} }
// 按照用户要求收到图像数据后将图像保存到LastImage中,调用更新 // 按照用户要求收到图像数据后将图像保存到LastImage中
lock (_lastImageLock) lock (_lastImageLock)
{ {
// 释放旧的LastImage资源 // 释放旧的LastImage资源
if (_lastImage != null) if (_lastImage != null)
{ {
try { _lastImage.Dispose(); } catch {} try { _lastImage.Dispose(); } catch {}
} }
// 设置新的LastImage // 设置新的LastImage
_lastImage = newImage; _lastImage = newImage;
} }
// 调用更新UI // 按照用户要求:调用更新UI
this.BeginInvoke(new Action(() => // 只有当图像更新未暂停时才更新UI
{ if (!_isPaused)
try {
{ this.BeginInvoke(new Action(() =>
UpdateImageOnUI(); {
} try
catch (Exception ex) {
{ UpdateImageOnUI();
Console.WriteLine($"更新UI图像失败: {ex.Message}"); }
} catch (Exception ex)
})); {
Console.WriteLine($"更新UI图像失败: {ex.Message}");
}
}));
}
} }
} }
} }
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine($"处理接收到的图像时出错: {ex.Message}"); Console.WriteLine($"处理接收到的图像时出错: {ex.Message}");
} }
} }
@@ -630,29 +673,6 @@ namespace JoyD.Windows.CS.Toprie
g.DrawString("测试信息", font, textBrush, 10, 10); g.DrawString("测试信息", font, textBrush, 10, 10);
} }
} }
// 检查是否需要绘制暂停状态的mask信息
bool isPaused = pauseImageUpdateToolStripMenuItem.Text == "恢复图像更新";
if (isPaused)
{
// 绘制半透明黑色背景
using (Brush brush = new SolidBrush(Color.FromArgb(100, Color.Black)))
{
g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT);
}
// 绘制"暂停"文字
using (Font font = new Font("微软雅黑", 48, FontStyle.Bold))
using (Brush textBrush = new SolidBrush(Color.White))
{
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
g.DrawString("暂停", font, textBrush,
new Rectangle(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format);
}
}
} }
} }
@@ -780,6 +800,7 @@ namespace JoyD.Windows.CS.Toprie
/// <summary> /// <summary>
/// 处理连接状态变更 /// 处理连接状态变更
/// 2、断开或连接时设置连接状态调用更新Info
/// </summary> /// </summary>
private void HandleConnectionStatusChanged(ConnectionStatusChangedEventArgs e) private void HandleConnectionStatusChanged(ConnectionStatusChangedEventArgs e)
{ {
@@ -808,10 +829,6 @@ namespace JoyD.Windows.CS.Toprie
case ConnectionStatus.Connected: case ConnectionStatus.Connected:
Console.WriteLine("设备已连接"); Console.WriteLine("设备已连接");
// 清除显示标志并刷新UI
_isDisplayingInfo = false;
UpdateImageOnUI();
// 仅在首次连接时设置为热图模式,重连时保留之前的模式 // 仅在首次连接时设置为热图模式,重连时保留之前的模式
if (!_isReceivingImage) // 首次连接时_isReceivingImage为false if (!_isReceivingImage) // 首次连接时_isReceivingImage为false
{ {
@@ -835,9 +852,19 @@ namespace JoyD.Windows.CS.Toprie
// 开始接收图像包含在try-catch中 // 开始接收图像包含在try-catch中
if (!_isReceivingImage) if (!_isReceivingImage)
{ {
StartReceiveImage(); try
{
StartReceiveImage();
}
catch (Exception ex)
{
Console.WriteLine($"开始接收图像失败: {ex.Message}");
}
} }
// 设置连接状态后调用更新Info
UpdateInfo();
break; break;
case ConnectionStatus.Disconnected: case ConnectionStatus.Disconnected:
Console.WriteLine("设备已断开连接"); Console.WriteLine("设备已断开连接");
@@ -857,39 +884,8 @@ namespace JoyD.Windows.CS.Toprie
} }
} }
// 在InfoImage中显示连接断开信息 // 设置连接状态后调用更新Info
lock (_infoImageLock) UpdateInfo();
{
// 如果_infoImage为null则创建新对象
if (_infoImage == null)
{
_infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT);
}
// 直接在现有InfoImage上重绘不需要Dispose
using (Graphics g = Graphics.FromImage(_infoImage))
{
// 设置半透明背景
using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Black)))
{
g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT);
}
// 绘制断开连接字样
using (Font font = new Font("Arial", 36, FontStyle.Bold))
using (SolidBrush textBrush = new SolidBrush(Color.Red))
{
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
g.DrawString("连接断开", font, textBrush, new RectangleF(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format);
}
}
}
// 设置显示信息标志并更新UI
_isDisplayingInfo = true;
UpdateImageOnUI();
if (!string.IsNullOrEmpty(e.DeviceInfo)) if (!string.IsNullOrEmpty(e.DeviceInfo))
{ {
@@ -908,39 +904,8 @@ namespace JoyD.Windows.CS.Toprie
Console.WriteLine($"正在重新连接设备...{(!string.IsNullOrEmpty(e.DeviceInfo) ? " " + e.DeviceInfo : "")}"); Console.WriteLine($"正在重新连接设备...{(!string.IsNullOrEmpty(e.DeviceInfo) ? " " + e.DeviceInfo : "")}");
ShowError(string.Empty); // 清除之前的错误信息 ShowError(string.Empty); // 清除之前的错误信息
// 在InfoImage中显示正在重连信息 // 设置重连状态后调用更新Info
lock (_infoImageLock) UpdateInfo();
{
// 如果_infoImage为null则创建新对象
if (_infoImage == null)
{
_infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT);
}
// 直接在现有InfoImage上重绘不需要Dispose
using (Graphics g = Graphics.FromImage(_infoImage))
{
// 设置半透明背景
using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Black)))
{
g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT);
}
// 绘制正在重连字样
using (Font font = new Font("Arial", 36, FontStyle.Bold))
using (SolidBrush textBrush = new SolidBrush(Color.Yellow))
{
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
g.DrawString("正在重连...", font, textBrush, new RectangleF(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format);
}
}
}
// 设置显示信息标志并更新UI
_isDisplayingInfo = true;
UpdateImageOnUI();
break; break;
} }
} }