using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using static System.Net.Mime.MediaTypeNames;
namespace LB_VisionControls
{
public class UserPictureBox : PictureBox, IDisposable
{
public UserPictureBox(Control parent)
{
Point location = Point.Empty;
Size size = parent.ClientSize;
_zoomMatrix = new Matrix();
_rect = new Rectangle(0, 0, size.Width, size.Height);
this.Location = location;
this.Size = size;
this.SizeMode = PictureBoxSizeMode.Zoom;
this.parent = parent;
RegisterEvent();
}
#region 变量
Control parent { get; set; }
private Bitmap _currentImage = null;
private readonly object _syncLock = new object();
public Bitmap Image
{
get => _currentImage;
set
{
//// 根据首先设置的图像大小来计算缩放比例
//try
//{
// if (_currentImage == null)
// {
// _imgWidth = value.Width;
// _imgHeight = value.Height;
// // 计算自适应缩放比例
// float zoomX = (float)parent.ClientSize.Width / _imgWidth;
// float zoomY = (float)parent.ClientSize.Height / _imgHeight;
// _zoom = Math.Min(zoomX, zoomY); // 取较小的比例保证完全显示
// }
//}
//catch { }
lock (_syncLock)
{
try
{
// 释放现有资源
DisposeCurrentImage();
if (value != null)
{
// 创建新图像副本
//_currentImage = new Bitmap(value);
SetBackImage(value);
}
Refresh();
}
catch (Exception ex)
{
// 记录错误或处理异常
Debug.WriteLine($"【{DateTime.Now:HH:mm:ss.fff}】图像设置失败: {ex.Message}");
DisposeCurrentImage();
}
}
}
}
private void DisposeCurrentImage()
{
try
{
if (_tBrush != null)
{
_tBrush.Dispose();
_tBrush = null;
}
if (_currentImage != null)
{
_currentImage.Dispose();
_currentImage = null;
}
}
catch { }
}
///
/// 用于内部激活是否重绘
///
private bool _mEnable = true;
///
/// 背景纹理画刷(设置图像后会将图像转换成纹理画刷,因为填充画刷的速度要比绘制图像的速度快得多)
///
private TextureBrush _tBrush;
///
/// 控件的矩形区域
///
private Rectangle _rect = new Rectangle();
///
/// 图像宽度
///
private int _imgWidth = 1;
///
/// 图像高度
///
private int _imgHeight = 1;
///
/// 按下平移键,鼠标在控件上的横坐标
///
private float _mouseDownX = 0.0f;
///
/// 按下平移键,鼠标在控件上的纵坐标
///
private float _mouseDownY = 0.0f;
///
/// 缩放系数
///
private float _zoom = 1.0f;
///
/// 图片左上角X轴的偏移量
///
private float _imgX = 0.0f;
///
/// 图片左上角Y轴的偏移量
///
private float _imgY = 0.0f;
///
/// 按下平移键,记录当前的_imgX
///
private float _imgStartX = 0.0f;
///
/// 按下平移键,记录当前的_imgY
///
private float _imgStartY = 0.0f;
///
/// 当前的缩放矩阵
///
private Matrix _zoomMatrix = new Matrix();
///
/// 最小缩放倍率
///
private float _minZoom = 0.05f;
///
/// 最大缩放倍率
///
private float _maxZoom = 50.0f;
///
/// 每次鼠标滚轮时,缩放系数的增量值
///
private float _mouseZoomDV = 0.05f;
///
/// 平移按键
///
private MouseButtons _translateBtn = MouseButtons.Left;
///
/// 指示是否正在执行平移操作
///
private bool _inTranslate = false;
#endregion
#region 属性
///
/// 获取是否正在执行平移操作
///
public bool InTranslate
{
get { return _inTranslate; }
protected set
{
if (value != _inTranslate)
{
_inTranslate = value;
if (value)
{
OnStartTranslate();
}
else
{
OnStopTranslate();
}
}
}
}
#endregion
#region 方法
///
/// 注册事件
///
public void RegisterEvent()
{
//this.MouseDoubleClick += new MouseEventHandler(_ctrl_MouseDoubleClick);
this.MouseDown += new MouseEventHandler(_ctrl_MouseDown);
this.MouseMove += new MouseEventHandler(_ctrl_MouseMove);
this.MouseUp += new MouseEventHandler(_ctrl_MouseUp);
this.MouseEnter += new EventHandler(_ctrl_MouseEnter);
this.MouseWheel += new MouseEventHandler(_ctrl_MouseWheel);
this.Paint += new PaintEventHandler(_ctrl_Paint);
this.MouseDoubleClick += new MouseEventHandler(_ctrl_MouseDoubleDown);
}
///
/// 释放背景纹理画刷
///
protected virtual void tBrushDispose()
{
if (_tBrush != null)
{
_tBrush.Dispose();
_tBrush = null;
}
}
///
/// 释放资源
///
public new void Dispose()
{
tBrushDispose();
if (_zoomMatrix != null)
{
_zoomMatrix.Dispose();
_zoomMatrix = null;
}
if (this != null)
base.Dispose();
}
///
/// 设置背景图像
///
///
public void SetBackImage(Bitmap img)
{
try
{
_mEnable = false;
tBrushDispose(); //释放当前纹理
if (img != null)
{
_imgWidth = img.Width;
_imgHeight = img.Height;
//当图像的水平分辨率和垂直分辨率不为96时,将图像转换成纹理画刷之后会导致图像自动被裁剪掉一部分
if (img.VerticalResolution != 96 || img.HorizontalResolution != 96)
{
//重新实例化一张图片之后,新图片的水平分辨率和垂直分辨率会自动调整为96
using (Bitmap bmp = new Bitmap(img))
{
_tBrush = new TextureBrush(img, WrapMode.Clamp);
}
}
else
_tBrush = new TextureBrush(img, WrapMode.Clamp);
}
else
{
_imgWidth = 1;
_imgHeight = 1;
}
NormalMatrix();
_mEnable = true;
ZoomImage(parent.ClientSize.Height / 2, parent.ClientSize.Width / 2, _zoom);
}
catch { }
}
///
/// 缩放图像
///
/// 缩放的中心点X
/// 缩放的中心点Y
/// 缩放系数
protected void ZoomImage(int x, int y, float zoom)
{
if (zoom >= _maxZoom)
zoom = _maxZoom;
else if (zoom < _minZoom)
zoom = _minZoom;
float oldX = x / _zoom;
float oldY = y / _zoom;
_zoom = zoom;
_imgX = x / zoom - oldX + _imgX;
_imgY = y / zoom - oldY + _imgY;
_zoomMatrix.Reset();
_zoomMatrix.Scale(zoom, zoom);
_zoomMatrix.Translate(_imgX, _imgY);
this.Refresh();
}
///
/// 归一化当前矩阵
///
protected virtual void NormalMatrix()
{
//_zoom = 1.0f;
//_imgX = 0.0f;
//_imgY = 0.0f;
//_zoomMatrix.Reset();
//_zoomMatrix.Scale(_zoom, _zoom);
//_zoomMatrix.Translate(_imgX, _imgY);
_zoomMatrix = new Matrix();
}
#endregion
#region 控件事件
private void _ctrl_Paint(object sender, PaintEventArgs e)
{
if (_mEnable)
{
Graphics g = e.Graphics;
g.InterpolationMode = InterpolationMode.HighQualityBicubic; //设置插值模式
if (_tBrush != null)
{
g.Transform = _zoomMatrix; //设置变换矩阵
g.FillRectangle(_tBrush, 0, 0, _imgWidth, _imgHeight);
}
}
}
private void _ctrl_MouseWheel(object sender, MouseEventArgs e)
{
if (_mEnable)
{
if (e.Delta >= 0)
ZoomImage(e.X, e.Y, _zoom + _mouseZoomDV);
else
ZoomImage(e.X, e.Y, _zoom - _mouseZoomDV);
}
}
private void _ctrl_MouseEnter(object sender, EventArgs e)
{
//为控件设置焦点,因为只有控件有焦点才能为控件触发鼠标滚轮事件
this.Focus();
}
private void _ctrl_MouseUp(object sender, MouseEventArgs e)
{
if (_mEnable)
{
if (e.Button == _translateBtn)
{
InTranslate = false;
}
}
}
private void _ctrl_MouseMove(object sender, MouseEventArgs e)
{
if (_mEnable)
{
if (_inTranslate)
{
float deltaX = e.X - _mouseDownX;
float deltaY = e.Y - _mouseDownY;
_imgX = _imgStartX + (deltaX / _zoom);
_imgY = _imgStartY + (deltaY / _zoom);
_zoomMatrix.Reset();
_zoomMatrix.Scale(_zoom, _zoom);
_zoomMatrix.Translate(_imgX, _imgY);
this.Refresh();
}
}
}
private void _ctrl_MouseDoubleDown(object sender, MouseEventArgs e)
{
if (_mEnable && _currentImage != null)
{
Bitmap Image = _currentImage.Clone() as Bitmap;
DisposeCurrentImage();
this.Image = Image;
}
}
private void _ctrl_MouseDown(object sender, MouseEventArgs e)
{
if (_mEnable)
{
if (e.Button == _translateBtn)
{
_mouseDownX = e.X;
_mouseDownY = e.Y;
_imgStartX = _imgX;
_imgStartY = _imgY;
InTranslate = true;
}
}
}
//private void _ctrl_MouseDoubleClick(object sender, MouseEventArgs e)
//{
// this.BeginInvoke(new Action(() =>
// {
// try
// {
// // 将 Image 保存为临时文件
// string tempFilePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".jpg");
// this.Image.Save(tempFilePath, System.Drawing.Imaging.ImageFormat.Jpeg);
// // 使用默认图片查看器打开临时图片
// Process.Start(tempFilePath);
// Thread.Sleep(1000);
// // 在操作系统打开图片后,你可以选择删除临时文件(可选)
// File.Delete(tempFilePath); // 如果希望在打开后删除临时文件,取消注释此行
// }
// catch { }
// }));
//}
#endregion
#region 自定义事件
///
/// 在开始平移时发生
///
public event EventHandler StartTranslate;
///
/// 在结束平移时发生
///
public event EventHandler StopTranslate;
///
/// 触发开始平移事件
///
protected virtual void OnStartTranslate()
{
if (StartTranslate != null)
{
StartTranslate(this, EventArgs.Empty);
}
}
///
/// 触发结束平移事件
///
protected virtual void OnStopTranslate()
{
if (StopTranslate != null)
{
StopTranslate(this, EventArgs.Empty);
}
}
#endregion
}
}