686 lines
26 KiB
C#
686 lines
26 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.Drawing.Drawing2D;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Windows.Forms;
|
||
|
||
namespace JoyD.Windows.CS
|
||
{
|
||
public partial class Setting : Form
|
||
{
|
||
// 创建并显示检测配置窗口
|
||
public static Setting Form = new Setting();
|
||
|
||
// 定时器字段
|
||
private Timer _timer;
|
||
|
||
// 绘制模式标志
|
||
private bool _isDrawingMode = false;
|
||
|
||
// 矩形绘制相关变量
|
||
private Point _startPoint;
|
||
private Rectangle _currentRectangle = Rectangle.Empty;
|
||
private bool _isDrawing = false;
|
||
private List<RegionInfo> _drawnRectangles = new List<RegionInfo>();
|
||
private Color _selectedColor = Color.Red;
|
||
private int _regionCounter = 0;
|
||
// 叠加层图像 - 用于存储已完成绘制的矩形
|
||
private Image _rectangleOverlayImage = null;
|
||
|
||
public Setting()
|
||
{
|
||
InitializeComponent();
|
||
|
||
// 订阅SizeChanged事件,确保控件大小变化时矩形框正确缩放
|
||
this.picBoxTemp.SizeChanged += new EventHandler(PicBoxTemp_SizeChanged);
|
||
|
||
// 设置按钮图标
|
||
SetButtonIcon();
|
||
|
||
// 初始化定时器
|
||
_timer = new Timer { Interval = 1000 };
|
||
_timer.Tick += Timer_Tick;
|
||
|
||
// 注册窗口事件
|
||
this.Shown += Setting_Shown;
|
||
this.FormClosing += Setting_FormClosing;
|
||
|
||
// 注册按钮点击事件
|
||
btnDrawRegion.Click += BtnDrawRegion_Click;
|
||
btnSelectColor.Click += BtnSelectColor_Click;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 绘制区域按钮点击事件
|
||
/// </summary>
|
||
private void BtnDrawRegion_Click(object sender, EventArgs e)
|
||
{
|
||
_isDrawingMode = btnDrawRegion.Checked;
|
||
|
||
if (_isDrawingMode)
|
||
{
|
||
// 启用绘制模式
|
||
picBoxTemp.MouseDown += PicBoxTemp_MouseDown;
|
||
picBoxTemp.MouseMove += PicBoxTemp_MouseMove;
|
||
picBoxTemp.MouseUp += PicBoxTemp_MouseUp;
|
||
picBoxTemp.Cursor = Cursors.Cross;
|
||
btnDrawRegion.ToolTipText = "绘制模式已启用,点击图片区域绘制矩形框(点击关闭)";
|
||
}
|
||
else
|
||
{
|
||
// 禁用绘制模式
|
||
picBoxTemp.MouseDown -= PicBoxTemp_MouseDown;
|
||
picBoxTemp.MouseMove -= PicBoxTemp_MouseMove;
|
||
picBoxTemp.MouseUp -= PicBoxTemp_MouseUp;
|
||
picBoxTemp.Cursor = Cursors.Default;
|
||
_currentRectangle = Rectangle.Empty;
|
||
btnDrawRegion.ToolTipText = "绘制温度检测区域(点击开启/关闭)";
|
||
// 重绘以清除临时矩形
|
||
picBoxTemp.Invalidate();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将控件坐标转换为图像坐标
|
||
/// </summary>
|
||
private Point ControlPointToImagePoint(Point controlPoint)
|
||
{
|
||
if (picBoxTemp.Image == null)
|
||
return controlPoint;
|
||
|
||
// 计算图像在控件中的缩放比例
|
||
float scaleX = (float)picBoxTemp.Image.Width / picBoxTemp.ClientSize.Width;
|
||
float scaleY = (float)picBoxTemp.Image.Height / picBoxTemp.ClientSize.Height;
|
||
|
||
// 计算图像坐标
|
||
return new Point(
|
||
(int)(controlPoint.X * scaleX),
|
||
(int)(controlPoint.Y * scaleY)
|
||
);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将图像坐标转换为控件坐标
|
||
/// </summary>
|
||
private Point ImagePointToControlPoint(Point imagePoint)
|
||
{
|
||
if (picBoxTemp.Image == null)
|
||
return imagePoint;
|
||
|
||
// 计算图像在控件中的缩放比例
|
||
float scaleX = (float)picBoxTemp.ClientSize.Width / picBoxTemp.Image.Width;
|
||
float scaleY = (float)picBoxTemp.ClientSize.Height / picBoxTemp.Image.Height;
|
||
|
||
// 计算控件坐标
|
||
return new Point(
|
||
(int)(imagePoint.X * scaleX),
|
||
(int)(imagePoint.Y * scaleY)
|
||
);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将图像矩形转换为控件矩形
|
||
/// </summary>
|
||
private Rectangle ImageRectangleToControlRectangle(Rectangle imageRectangle)
|
||
{
|
||
if (picBoxTemp.Image == null)
|
||
return imageRectangle;
|
||
|
||
// 计算图像在控件中的缩放比例
|
||
float scaleX = (float)picBoxTemp.ClientSize.Width / picBoxTemp.Image.Width;
|
||
float scaleY = (float)picBoxTemp.ClientSize.Height / picBoxTemp.Image.Height;
|
||
|
||
// 计算控件矩形
|
||
return new Rectangle(
|
||
(int)(imageRectangle.X * scaleX),
|
||
(int)(imageRectangle.Y * scaleY),
|
||
(int)(imageRectangle.Width * scaleX),
|
||
(int)(imageRectangle.Height * scaleY)
|
||
);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 鼠标按下事件 - 开始绘制矩形
|
||
/// </summary>
|
||
private void PicBoxTemp_MouseDown(object sender, MouseEventArgs e)
|
||
{
|
||
if (e.Button == MouseButtons.Left && _isDrawingMode)
|
||
{
|
||
_startPoint = e.Location;
|
||
_isDrawing = true;
|
||
_currentRectangle = new Rectangle(e.X, e.Y, 0, 0);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 鼠标移动事件 - 更新矩形大小
|
||
/// </summary>
|
||
private void PicBoxTemp_MouseMove(object sender, MouseEventArgs e)
|
||
{
|
||
if (_isDrawing && _isDrawingMode)
|
||
{
|
||
int width = e.X - _startPoint.X;
|
||
int height = e.Y - _startPoint.Y;
|
||
|
||
_currentRectangle = new Rectangle(
|
||
width > 0 ? _startPoint.X : _startPoint.X + width,
|
||
height > 0 ? _startPoint.Y : _startPoint.Y + height,
|
||
Math.Abs(width),
|
||
Math.Abs(height));
|
||
|
||
picBoxTemp.Invalidate();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 存储区域信息的类,包含矩形框(图像坐标)、颜色和序号
|
||
/// </summary>
|
||
private class RegionInfo
|
||
{
|
||
// 存储相对于图像的矩形坐标
|
||
public Rectangle ImageRectangle { get; set; }
|
||
public Color Color { get; set; }
|
||
public int Index { get; set; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建或更新叠加层图像(完全重绘)
|
||
/// 仅在必要时调用,如图像尺寸改变或需要完全重绘
|
||
/// 使用图像坐标绘制矩形
|
||
/// </summary>
|
||
private void CreateRectangleOverlayImage()
|
||
{
|
||
// 如果PictureBox没有图像或者尺寸为0,则不创建叠加层
|
||
if (picBoxTemp.Image == null || picBoxTemp.Image.Width == 0 || picBoxTemp.Image.Height == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 如果叠加层图像不存在或尺寸不匹配,创建新的
|
||
if (_rectangleOverlayImage == null ||
|
||
_rectangleOverlayImage.Width != picBoxTemp.Image.Width ||
|
||
_rectangleOverlayImage.Height != picBoxTemp.Image.Height)
|
||
{
|
||
// 释放旧的叠加层图像资源
|
||
if (_rectangleOverlayImage != null)
|
||
{
|
||
_rectangleOverlayImage.Dispose();
|
||
}
|
||
|
||
// 创建新的叠加层图像
|
||
_rectangleOverlayImage = new Bitmap(picBoxTemp.Image.Width, picBoxTemp.Image.Height);
|
||
|
||
// 清除背景为透明
|
||
using (Graphics g = Graphics.FromImage(_rectangleOverlayImage))
|
||
{
|
||
g.Clear(Color.Transparent);
|
||
}
|
||
|
||
// 由于创建了新图像,需要重新绘制所有矩形
|
||
foreach (RegionInfo region in _drawnRectangles)
|
||
{
|
||
DrawRegionToOverlay(region);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 清除现有叠加层图像
|
||
using (Graphics g = Graphics.FromImage(_rectangleOverlayImage))
|
||
{
|
||
g.Clear(Color.Transparent);
|
||
}
|
||
|
||
// 重绘所有矩形
|
||
foreach (RegionInfo region in _drawnRectangles)
|
||
{
|
||
DrawRegionToOverlay(region);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将单个区域绘制到叠加层图像
|
||
/// 用于增量绘制,避免每次都重绘所有矩形
|
||
/// 使用图像坐标绘制矩形
|
||
/// </summary>
|
||
/// <param name="region">要绘制的区域信息</param>
|
||
private void DrawRegionToOverlay(RegionInfo region)
|
||
{
|
||
if (_rectangleOverlayImage == null)
|
||
return;
|
||
|
||
using (Graphics g = Graphics.FromImage(_rectangleOverlayImage))
|
||
{
|
||
// 设置高质量绘图
|
||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||
|
||
// 使用每个区域自己的颜色绘制矩形
|
||
g.DrawRectangle(new Pen(region.Color, 2), region.ImageRectangle);
|
||
|
||
// 绘制区域序号
|
||
using (Font font = new Font("Arial", 12, FontStyle.Bold))
|
||
using (SolidBrush brush = new SolidBrush(region.Color))
|
||
{
|
||
// 在矩形左上角绘制序号
|
||
Point textPosition = new Point(region.ImageRectangle.X + 5, region.ImageRectangle.Y - 15);
|
||
// 确保文本不超出图像边界
|
||
if (textPosition.Y < 0)
|
||
textPosition.Y = 5;
|
||
|
||
g.DrawString(region.Index.ToString(), font, brush, textPosition);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 鼠标释放事件 - 完成矩形绘制(优化版)
|
||
/// 使用增量绘制,避免每次都重绘所有矩形
|
||
/// 确保矩形坐标相对于图像而非控件
|
||
/// </summary>
|
||
private void PicBoxTemp_MouseUp(object sender, MouseEventArgs e)
|
||
{
|
||
if (_isDrawing && _isDrawingMode && e.Button == MouseButtons.Left && picBoxTemp.Image != null)
|
||
{
|
||
_isDrawing = false;
|
||
|
||
// 获取相对于图像的矩形坐标
|
||
Point imageStartPoint = ControlPointToImagePoint(new Point(_currentRectangle.X, _currentRectangle.Y));
|
||
Point imageEndPoint = ControlPointToImagePoint(new Point(_currentRectangle.Right, _currentRectangle.Bottom));
|
||
|
||
// 确保矩形有一定大小才添加(转换为图像坐标后检查)
|
||
int imageWidth = Math.Abs(imageEndPoint.X - imageStartPoint.X);
|
||
int imageHeight = Math.Abs(imageEndPoint.Y - imageStartPoint.Y);
|
||
|
||
if (imageWidth > 5 && imageHeight > 5)
|
||
{
|
||
// 计算图像坐标的矩形(确保左上角为起始点)
|
||
int imageX = Math.Min(imageStartPoint.X, imageEndPoint.X);
|
||
int imageY = Math.Min(imageStartPoint.Y, imageEndPoint.Y);
|
||
|
||
// 增加计数器并创建新的区域信息(存储图像坐标)
|
||
_regionCounter++;
|
||
RegionInfo regionInfo = new RegionInfo
|
||
{
|
||
ImageRectangle = new Rectangle(imageX, imageY, imageWidth, imageHeight),
|
||
Color = _selectedColor,
|
||
Index = _regionCounter
|
||
};
|
||
|
||
_drawnRectangles.Add(regionInfo);
|
||
|
||
// 检查是否需要完全重建叠加层
|
||
bool needFullRebuild = false;
|
||
|
||
// 如果叠加层不存在或尺寸不匹配,需要完全重建
|
||
if (_rectangleOverlayImage == null ||
|
||
_rectangleOverlayImage.Width != picBoxTemp.Image.Width ||
|
||
_rectangleOverlayImage.Height != picBoxTemp.Image.Height)
|
||
{
|
||
needFullRebuild = true;
|
||
}
|
||
|
||
if (needFullRebuild)
|
||
{
|
||
// 完全重建叠加层
|
||
CreateRectangleOverlayImage();
|
||
}
|
||
else
|
||
{
|
||
// 仅绘制新添加的矩形(增量绘制)
|
||
DrawRegionToOverlay(regionInfo);
|
||
}
|
||
|
||
// 显示绘制完成的提示
|
||
ToolStripStatusLabel statusLabel = new ToolStripStatusLabel
|
||
{
|
||
Text = string.Format("已添加检测区域{0}: 图像坐标 - X={1}, Y={2}, 宽={3}, 高={4}",
|
||
_regionCounter,
|
||
imageX, imageY, imageWidth, imageHeight)
|
||
};
|
||
// 如果有状态栏,可以添加到状态栏显示
|
||
}
|
||
|
||
_currentRectangle = Rectangle.Empty;
|
||
picBoxTemp.Invalidate();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 绘制事件 - 显示矩形框(实现图像合并机制)
|
||
/// 处理叠加层图像的缩放,确保与控件尺寸匹配
|
||
/// </summary>
|
||
private void PicBoxTemp_Paint(object sender, PaintEventArgs e)
|
||
{
|
||
// 设置高质量绘图
|
||
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||
|
||
// 图像合并机制:先绘制叠加层(根据控件尺寸进行缩放)
|
||
if (_rectangleOverlayImage != null && picBoxTemp.Image != null)
|
||
{
|
||
// 计算缩放后的目标矩形
|
||
Rectangle destRect = new Rectangle(0, 0, picBoxTemp.ClientSize.Width, picBoxTemp.ClientSize.Height);
|
||
// 绘制缩放后的叠加层
|
||
e.Graphics.DrawImage(_rectangleOverlayImage, destRect, 0, 0, _rectangleOverlayImage.Width, _rectangleOverlayImage.Height, GraphicsUnit.Pixel);
|
||
}
|
||
|
||
// 再绘制临时矩形(当前正在绘制的矩形,使用控件坐标)
|
||
if (!_currentRectangle.IsEmpty && _isDrawingMode && _isDrawing)
|
||
{
|
||
using (Pen dashedPen = new Pen(Color.Blue, 2))
|
||
{
|
||
dashedPen.DashPattern = new float[] { 5, 2 };
|
||
e.Graphics.DrawRectangle(dashedPen, _currentRectangle);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置绘制区域按钮的图标
|
||
/// </summary>
|
||
private void SetButtonIcon()
|
||
{
|
||
// 创建一个表示绘制区域的图标
|
||
Bitmap icon = new Bitmap(24, 24);
|
||
using (Graphics g = Graphics.FromImage(icon))
|
||
{
|
||
// 设置高质量绘图
|
||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||
|
||
// 清除背景为透明
|
||
g.Clear(Color.Transparent);
|
||
|
||
// 绘制外矩形
|
||
g.DrawRectangle(new Pen(Color.Black, 2), 3, 3, 18, 18);
|
||
|
||
// 绘制虚线内矩形
|
||
using (Pen dashedPen = new Pen(Color.Black, 1.5f))
|
||
{
|
||
dashedPen.DashPattern = new float[] { 2, 1 };
|
||
g.DrawRectangle(dashedPen, 5, 5, 14, 14);
|
||
}
|
||
|
||
// 绘制四个角的控制点
|
||
SolidBrush brush = new SolidBrush(Color.Black);
|
||
g.FillEllipse(brush, 6, 6, 3, 3); // 左上角
|
||
g.FillEllipse(brush, 15, 6, 3, 3); // 右上角
|
||
g.FillEllipse(brush, 6, 15, 3, 3); // 左下角
|
||
g.FillEllipse(brush, 15, 15, 3, 3); // 右下角
|
||
}
|
||
|
||
// 设置按钮图标并设置透明色
|
||
btnDrawRegion.Image = icon;
|
||
btnDrawRegion.ImageTransparentColor = Color.Transparent;
|
||
|
||
// 设置颜色选择按钮的图标
|
||
UpdateColorButtonIcon();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新颜色选择按钮的图标,显示_selectedColor颜色的矩形
|
||
/// </summary>
|
||
private void UpdateColorButtonIcon()
|
||
{
|
||
// 创建颜色选择按钮的图标
|
||
Bitmap colorIcon = new Bitmap(24, 24);
|
||
using (Graphics g = Graphics.FromImage(colorIcon))
|
||
{
|
||
// 设置高质量绘图
|
||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||
|
||
// 清除背景为透明
|
||
g.Clear(Color.Transparent);
|
||
|
||
// 绘制边框
|
||
g.DrawRectangle(new Pen(Color.Black, 1), 3, 3, 18, 18);
|
||
|
||
// 使用_selectedColor填充矩形
|
||
using (SolidBrush brush = new SolidBrush(_selectedColor))
|
||
{
|
||
g.FillRectangle(brush, 4, 4, 16, 16);
|
||
}
|
||
}
|
||
|
||
// 设置按钮图标并设置透明色
|
||
btnSelectColor.Image = colorIcon;
|
||
btnSelectColor.ImageTransparentColor = Color.Transparent;
|
||
|
||
// 启用双缓冲以减少闪烁
|
||
typeof(PictureBox).InvokeMember("DoubleBuffered",
|
||
System.Reflection.BindingFlags.SetProperty |
|
||
System.Reflection.BindingFlags.Instance |
|
||
System.Reflection.BindingFlags.NonPublic,
|
||
null, picBoxTemp, new object[] { true });
|
||
}
|
||
|
||
/// <summary>
|
||
/// 颜色选择按钮点击事件
|
||
/// </summary>
|
||
private void BtnSelectColor_Click(object sender, EventArgs e)
|
||
{
|
||
using (ColorDialog colorDialog = new ColorDialog())
|
||
{
|
||
// 设置初始颜色为当前选中的颜色
|
||
colorDialog.Color = _selectedColor;
|
||
|
||
// 允许自定义颜色
|
||
colorDialog.AllowFullOpen = true;
|
||
colorDialog.FullOpen = true;
|
||
|
||
// 显示颜色选择对话框
|
||
if (colorDialog.ShowDialog() == DialogResult.OK)
|
||
{
|
||
// 更新选中的颜色
|
||
_selectedColor = colorDialog.Color;
|
||
|
||
// 更新按钮图标,显示新选择的颜色
|
||
UpdateColorButtonIcon();
|
||
|
||
// 重绘图片区域,显示新颜色的矩形
|
||
picBoxTemp.Invalidate();
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 窗口显示时启动定时器
|
||
/// </summary>
|
||
private void Setting_Shown(object sender, EventArgs e)
|
||
{
|
||
// 仅在非设计模式下启动定时器
|
||
if (!DesignMode)
|
||
{
|
||
_timer.Start();
|
||
|
||
// 立即执行一次定时器事件,避免首次显示时的延迟
|
||
Timer_Tick(sender, e);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 窗口关闭时停止定时器并释放资源
|
||
/// </summary>
|
||
private void Setting_FormClosing(object sender, FormClosingEventArgs e)
|
||
{
|
||
_timer.Stop();
|
||
|
||
// 释放叠加层图像资源
|
||
if (_rectangleOverlayImage != null)
|
||
{
|
||
_rectangleOverlayImage.Dispose();
|
||
_rectangleOverlayImage = null;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 定时器每秒触发的事件处理方法
|
||
/// </summary>
|
||
/// <summary>
|
||
/// 当图像更新或控件大小变化时,重新创建叠加层图像
|
||
/// 确保矩形框正确显示在新的尺寸下
|
||
/// </summary>
|
||
private void UpdateOverlayForSizeChange()
|
||
{
|
||
if (picBoxTemp.Image != null && _drawnRectangles.Count > 0)
|
||
{
|
||
CreateRectangleOverlayImage();
|
||
picBoxTemp.Invalidate();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 当控件大小改变时,更新叠加层以确保矩形框正确缩放
|
||
/// </summary>
|
||
private void PicBoxTemp_SizeChanged(object sender, EventArgs e)
|
||
{
|
||
UpdateOverlayForSizeChange();
|
||
}
|
||
|
||
private void Timer_Tick(object sender, EventArgs e)
|
||
{
|
||
// 这里可以添加每秒需要执行的代码
|
||
// 例如:更新界面数据、检查状态等
|
||
if (DesignMode || this.IsDisposed || this.Disposing)
|
||
return;
|
||
|
||
// 线程安全检查 - 确保在UI线程上执行
|
||
if (this.InvokeRequired)
|
||
{
|
||
try
|
||
{
|
||
this.BeginInvoke(new Action(UpdatePictureBoxImage));
|
||
}
|
||
catch (ObjectDisposedException)
|
||
{
|
||
// 控件已释放,忽略
|
||
}
|
||
return;
|
||
}
|
||
|
||
UpdatePictureBoxImage();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新PictureBox图像的辅助方法
|
||
/// 此方法必须在UI线程上执行
|
||
/// </summary>
|
||
private void UpdatePictureBoxImage()
|
||
{
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新pictureBoxTemperatureDisplay的图像
|
||
/// 此方法可以从任何线程调用
|
||
/// 注意:根据要求,不修改此方法的核心逻辑
|
||
/// </summary>
|
||
/// <param name="NewImage">要显示的新图像</param>
|
||
public void UpdateRealTimeImage(Image NewImage)
|
||
{
|
||
// 空值检查
|
||
if (NewImage == null)
|
||
{
|
||
Console.WriteLine("传入UpdateRealTimeImage的图像为空");
|
||
return;
|
||
}
|
||
|
||
// 检查是否处于设计模式或窗口不可见
|
||
if (DesignMode || !this.Visible || this.IsDisposed || this.Disposing)
|
||
{
|
||
// 如果不满足条件,释放图像资源并返回
|
||
NewImage.Dispose();
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
// 线程安全检查 - 确保在UI线程上执行
|
||
if (this.InvokeRequired)
|
||
{
|
||
try
|
||
{
|
||
// 使用BeginInvoke在UI线程上更新图像
|
||
this.BeginInvoke(new Action(() =>
|
||
{
|
||
try
|
||
{
|
||
// 确保窗口未被释放
|
||
if (!this.IsDisposed && !this.Disposing && picBoxTemp != null && !picBoxTemp.IsDisposed)
|
||
{
|
||
// 保存旧图像引用,以便在设置新图像后释放
|
||
Image oldImage = picBoxTemp.Image;
|
||
|
||
// 设置新图像
|
||
picBoxTemp.Image = NewImage;
|
||
|
||
// 释放旧图像资源
|
||
if (oldImage != null && oldImage != NewImage)
|
||
{
|
||
oldImage.Dispose();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 如果控件已释放,确保释放图像资源
|
||
NewImage.Dispose();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"更新设置窗口图像失败: {ex.Message}");
|
||
// 确保在异常情况下释放图像资源
|
||
try
|
||
{
|
||
NewImage.Dispose();
|
||
}
|
||
catch {}
|
||
}
|
||
}));
|
||
}
|
||
catch (ObjectDisposedException)
|
||
{
|
||
// 控件已释放,忽略并释放图像资源
|
||
NewImage.Dispose();
|
||
}
|
||
return;
|
||
}
|
||
|
||
// 在UI线程上直接更新图像
|
||
if (!this.IsDisposed && !this.Disposing && picBoxTemp != null && !picBoxTemp.IsDisposed)
|
||
{
|
||
// 保存旧图像引用,以便在设置新图像后释放
|
||
Image oldImage = picBoxTemp.Image;
|
||
|
||
// 设置新图像
|
||
picBoxTemp.Image = NewImage;
|
||
|
||
// 释放旧图像资源
|
||
if (oldImage != null && oldImage != NewImage)
|
||
{
|
||
oldImage.Dispose();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 如果控件已释放,确保释放图像资源
|
||
NewImage.Dispose();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"处理实时图像更新时出错: {ex.Message}");
|
||
// 确保在任何异常情况下都释放图像资源
|
||
try
|
||
{
|
||
NewImage.Dispose();
|
||
}
|
||
catch {}
|
||
}
|
||
}
|
||
}
|
||
} |