Winform 自定义PictureBox控件实现缩放和图片拖动

    public class CustomPictureBox : PictureBox
    {
      
        private Point _dragStart;
        private bool _dragging = false;
        private Point _imageLocation = new Point(0, 0);
        private float _zoomFactor = 1.0f;
        private bool _firstFlag = true;
        private float InitZoom=1.0f;//记录缩放倍数
        
        /// <summary>
        /// 放大
        /// </summary>
        /// <param name="num"></param>
        public void Amplify(int num)
        {
            _zoomFactor *= (float)num; // 放大
            InitZoom *= num;
            this.Invalidate();
        }

        public void Reset()
        {
            _firstFlag = true;
        }
        /// <summary>
        /// 还原
        /// </summary>
        public void AmplifyInit()
        {
            _zoomFactor /= (float)InitZoom;
            InitZoom = 1.0f;
            _imageLocation = new Point(0, 0);
            this.Invalidate();
        }
        public CustomPictureBox()
        {
            this.DoubleBuffered = true;
            this.MouseWheel += ZoomableMoveablePictureBox_MouseWheel;
            this.MouseDown += ZoomableMoveablePictureBox_MouseDown;
            this.MouseMove += ZoomableMoveablePictureBox_MouseMove;
            this.MouseUp += ZoomableMoveablePictureBox_MouseUp;
            this.Paint += ZoomableMoveablePictureBox_Paint;
            this.Resize += (s, e) => this.Invalidate(); // 处理控件大小变化
          
        }

        private void ZoomableMoveablePictureBox_MouseWheel(object sender, MouseEventArgs e)
        {
            if (e.Delta > 0)
            {
                _zoomFactor *= 1.0f; // 放大
                InitZoom *= 1.0f;
            }
            else
            {
                _zoomFactor /= 1.1f; // 缩小
                InitZoom /= 1.1f;
            }
            _zoomFactor = Math.Max(0.1f, _zoomFactor); // 限制最小缩放比例
           
            this.Invalidate();
        }

        private void ZoomableMoveablePictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _dragStart = e.Location;
                _dragging = true;
            }
        }

        private void ZoomableMoveablePictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (_dragging && this.Image != null)
            {
                float moveFactor = 2.0f; // 调整拖动灵敏度
                var deltaX = (e.X - _dragStart.X) * moveFactor;
                var deltaY = (e.Y - _dragStart.Y) * moveFactor;
                _imageLocation.X += (int)deltaX;
                _imageLocation.Y += (int)deltaY;
                _dragStart = e.Location;
                this.Invalidate(); // 触发重新绘制
            }
        }

        private void ZoomableMoveablePictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _dragging = false;
            }
        }

        private void ZoomableMoveablePictureBox_Paint(object sender, PaintEventArgs e)
        {
            if (this.Image != null)
            {
                Rectangle srcRect = new Rectangle(0, 0, this.Image.Width, this.Image.Height);
                if (_firstFlag)//初始图片比例缩放、位置
                {
                    float w = (float)this.Width / (float)Image.Width;
                    float h = (float)this.Height / (float)Image.Height;
                    _zoomFactor = Math.Min((float)w, (float)h);
                    _imageLocation = new Point(0, 0);
                    _firstFlag = false;
                }

                Rectangle destRect = new Rectangle(
                   _imageLocation.X,
                   _imageLocation.Y,
                   (int)(this.Image.Width * _zoomFactor),
                   (int)(this.Image.Height * _zoomFactor)
               );


                // 计算控件中间的位置
                float centerX = (this.Width - destRect.Width) / 2;
                float centerY = (this.Height - destRect.Height) / 2;

                // 应用中心化和缩放
                destRect.X = (int)(centerX + _imageLocation.X);
                destRect.Y = (int)(centerY + _imageLocation.Y);

                e.Graphics.Clear(System.Drawing.Color.White); // 清除背景
                e.Graphics.DrawImage(this.Image, destRect, srcRect, GraphicsUnit.Pixel);
            }
            else
            {
                // 如果没有图片,背景填充为白色
                e.Graphics.Clear(System.Drawing.Color.White);
            }
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值