LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

【C#】Winform自定义图像控件实现滚动缩放效果、拖动显示图像

admin
2025年3月30日 17:26 本文热度 89

 本文描述了如何使用Winform创建用户图像控件、实现滚动缩放效果,拖动显示图像。



前言                           


    PictureBox 是 Windows Forms (WinForms) 中的一个内置控件,专门用于在窗体上显示图像,其可以显示多种格式的图像(如:BMP、JPEG、GIF、PNG、ICO 等)。

    PictureBox 内置了如下几种图像显示方式:

Normal:图像放置在控件的左上角,不缩放。

StretchImage:拉伸图像以填充控件。

AutoSize:调整控件大小以适应图像。

CenterImage:图像居中显示,不缩放。

Zoom:按比例缩放图像,保持纵横比。

    上面的图像显示方法只能实现基本的图像功能,。如果想要实现更好的体验效果。还需要自定义一些功能,下面就是自定义一个图像用户控件实现滚动鼠标缩放图像、鼠标拖动显示图像。


运行环境                     

系      统:Win11

开发工具:Visual Studio 2022

相关技术:C# 、Winform .Net Framework 4.6.0

实现功能                     

1、鼠标双击还原

2、鼠标滚动缩放:放大、缩小

3、点击按钮:放大、缩小、还原

4、鼠标按住拖动图像


 运行效果                     


01


图像控件代码

下面是自定义图像控件代码:

 public partial class UCPictrueBox : UserControl {     #region 字段、属性     #region 字段     private Image _image;                           //图像     private float _zoomFactor = 1.0f;               //缩放因子     private const float ZoomIncrement = 0.1f;       //缩放增量     private const float MinZoom = 0.01f;            //最小缩放     private const float MaxZoom = 20.0f;            //最大缩放     private Point _lastLocation;                    //最后位置     private bool _isDragging = false;               //是否拖拽     private PointF _imagePosition = PointF.Empty;   //图像位置     #endregion     #region 属性      [Description("获取或设置控件显示的图像。")]     [Category("UserDefine")]     public Image Image     {         get => _image;         set         {             _image = value;             _zoomFactor = 1.0f;             _imagePosition = PointF.Empty;             ImageCenter();             Invalidate();         }     }     #endregion     #endregion     #region 构造函数     public UCPictrueBox()     {         InitializeComponent();         this.DoubleBuffered = true;         this.BackColor = Color.LightGray;         this.BorderStyle = BorderStyle.FixedSingle;         this.MouseWheel += ImageZoom_MouseWheel;         this.MouseDown += ImageZoom_MouseDown;         this.MouseMove += ImageZoom_MouseMove;         this.MouseUp += ImageZoom_MouseUp;         this.MouseDoubleClick += ImageZoom_MouseDoubleClick;     }     #endregion     #region 图像操作     /// <summary>     /// 图像居中:使图像在水平和垂直方向上都居中     /// (X,Y) = ( (workWidth - ScaledWidth)/2, (workHeight - ScaledHeight)/2)     /// </summary>     private void ImageCenter()     {         if (_image == nullreturn;         Size scaledSize = GetScaledSize();         _imagePosition = new PointF((this.ClientSize.Width - scaledSize.Width) / 2f, (this.ClientSize.Height - scaledSize.Height) / 2f);         Invalidate();     }     /// <summary>     /// 图像缩放:基于鼠标位置的缩放     /// </summary>     private void Zoom(float factor)     {         if (_image == nullreturn;         //获取鼠标光标位置 转换为 工作区坐标。         Point mousePos = this.PointToClient(MousePosition);         Size scaledSize = GetScaledSize();         float mouseXRelative = (mousePos.X - _imagePosition.X) / scaledSize.Width;         float mouseYRelative = (mousePos.Y - _imagePosition.Y) / scaledSize.Height;         // 新缩放因子 = 当前缩放因子 + 传入的缩放增量         float newZoom = _zoomFactor + factor;         // 使用Math.Max和Math.Min确保缩放因子在最小(MinZoom)和最大(MaxZoom)限制之间         newZoom = Math.Max(MinZoom, Math.Min(MaxZoom, newZoom));         //如果没有显著变化,则不执行任何操作,条件:(缩放因子> 0.01)         if (Math.Abs(newZoom - _zoomFactor) > 0.01f)         {             _zoomFactor = newZoom;             Size newSize = GetScaledSize();             //调整图像位置:(X,Y) = ( (workWidth - ScaledWidth)/2, (workHeight - ScaledHeight)/2)             _imagePosition = new PointF(mousePos.X - mouseXRelative * newSize.Width, mousePos.Y - mouseYRelative * newSize.Height);             //如果缩放后的图像完全适合工作区(小于等于工作区尺寸),则调用ImageCenter()使其居中             if (newSize.Width <= this.ClientSize.Width && newSize.Height <= this.ClientSize.Height)             {                 ImageCenter();             }             Invalidate();         }     }     /// <summary>     /// 放大     /// </summary>     public void ZoomIn()     {         Zoom(ZoomIncrement);     }     /// <summary>     /// 缩小     /// </summary>     public void ZoomOut()     {         Zoom(-ZoomIncrement);     }     /// <summary>     /// 还原     /// </summary>     public void ZoomReset()     {         _zoomFactor = 1.0f;         ImageCenter();     }     /// <summary>     ///  计算图像缩放尺寸:(newW ,newH) =(width ,height)* zoomFactor     /// </summary>     private Size GetScaledSize()     {         return new Size((int)(_image.Width * _zoomFactor), (int)(_image.Height * _zoomFactor));     }     #endregion     #region 事件方法重写     /// <summary>     /// 重绘     /// </summary>     protected override void OnPaint(PaintEventArgs e)     {         base.OnPaint(e);         if (_image == nullreturn;         Size scaleSize = GetScaledSize();         Rectangle destRect;         if (_imagePosition == PointF.Empty)         {             int x = (this.ClientSize.Width - scaleSize.Width) / 2;             int y = (this.ClientSize.Height - scaleSize.Height) / 2;             destRect = new Rectangle(x, y, scaleSize.Width, scaleSize.Height);         }         else         {             destRect = new Rectangle(                 (int)_imagePosition.X,                 (int)_imagePosition.Y,                 scaleSize.Width,                 scaleSize.Height);         }         // 绘制图像         e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;         e.Graphics.DrawImage(_image, destRect);     }     /// <summary>     /// 重设大小     /// </summary>     protected override void OnResize(EventArgs e)     {         base.OnResize(e);         if (_image != null)         {             // 如果图像比控件小,则居中显示             Size scaledSize = GetScaledSize();             if (scaledSize.Width <= this.ClientSize.Width && scaledSize.Height <= this.ClientSize.Height)             {                 ImageCenter();             }         }     }     #endregion     #region 鼠标事件处理:滚轮缩放、按下拖拽、移动显示、松开取消拖拽、双击还原     private void ImageZoom_MouseWheel(object sender, MouseEventArgs e)     {         if (e.Delta > 0)         {             ZoomIn();         }         else if (e.Delta < 0)         {             ZoomOut();         }     }     private void ImageZoom_MouseDown(object sender, MouseEventArgs e)     {         if (e.Button == MouseButtons.Left && _image != null)         {             _lastLocation = e.Location;             _isDragging = true;             this.Cursor = Cursors.Hand;         }     }     private void ImageZoom_MouseMove(object sender, MouseEventArgs e)     {         if (_isDragging && _image != null)         {             int deltaX = e.X - _lastLocation.X;             int deltaY = e.Y - _lastLocation.Y;             _imagePosition.X += deltaX;             _imagePosition.Y += deltaY;             _lastLocation = e.Location;             Invalidate();         }     }     private void ImageZoom_MouseUp(object sender, MouseEventArgs e)     {         _isDragging = false;         this.Cursor = Cursors.Default;     }     private void ImageZoom_MouseDoubleClick(object sender, MouseEventArgs e)     {         ZoomReset();     }     #endregion }

02

窗体代码

    窗体代码,添加3个按钮即可。

public partial class MainForm : WinFormBase{    public MainForm()    {        InitializeComponent();        this.CenterToParent();        this.CenterToScreen();    }    private void btn_ZoomIn_Click(object sender, System.EventArgs e)    {        ucPic_Image.ZoomIn();    }    private void btn_ZoomOut_Click(object sender, System.EventArgs e)    {        ucPic_Image.ZoomOut();    }    private void btn_Reset_Click(object sender, System.EventArgs e)    {        string filePath = Application.StartupPath + "\\source.png";        ucPic_Image.Image = Image.FromFile(filePath);    }}

03


结语

    使用方法,将自定义控件创建在同一个命名空间下,点击生成无报错后,即可在工具箱中查看选择自定义控件。拖拽到当前窗体即可。

如果是引用自定义控件类库分类实现,引用时可能得报错原因,目标框架不同。

如果想使用图中自定义窗体请查看。

WinForm自定义控件及窗体

编程笔记in,公众号:编程笔记in【C#】WinForm自定义控件及窗体


阅读原文:原文链接


该文章在 2025/3/31 11:17:09 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved