C# 图片按锚点缩放

基于这篇文章进行优化,详细解析参考此文章

主要优化:
代码简洁化
图片缩小效果更顺畅

窗体后台代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Threading;

namespace NetFramework4._0Demo
{
    public partial class ImageZoon_图片缩放_ : Form
    {
        public Point mouseDownPoint;
        public bool isMove;
        public const int zoomStep = 50;

        public ImageZoon_图片缩放_()
        {
            InitializeComponent();
            #region 创建控件属性,事件
            this.pictureBox1.MouseDown += new MouseEventHandler(this.pictureBox1_MouseDown);
            this.pictureBox1.MouseMove += new MouseEventHandler(this.pictureBox1_MouseMove);
            this.pictureBox1.MouseUp += new MouseEventHandler(this.pictureBox1_MouseUp);
            this.pictureBox1.MouseWheel += new MouseEventHandler(this.pictureBox1_MouseWheel);//创建鼠标滑轮监听事件
            this.pictureBox1.Image = Properties.Resources.test;
            pictureBoxImgage();
            this.pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
            //如果想要鼠标不在pictureBox1控件上也可以缩放就注释下面一行代码
            this.panel1.MouseMove += new MouseEventHandler(panel1_MouseMove);
            #endregion
            
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            pictureBox1.Focus();
            if (e.Button == MouseButtons.Left)
            {
                mouseDownPoint.X = Cursor.Position.X; //记录鼠标左键按下时位置
                mouseDownPoint.Y = Cursor.Position.Y;
                isMove = true;
            }
        }

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

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            pictureBox1.Focus(); //鼠标在picturebox上时才有焦点,此时可以缩放
            if (isMove)
            {
                int x, y; //新的pictureBox1.Location(x,y)
                int moveX, moveY; //X方向,Y方向移动大小。
                moveX = Cursor.Position.X - mouseDownPoint.X;
                moveY = Cursor.Position.Y - mouseDownPoint.Y;
                x = pictureBox1.Location.X + moveX;
                y = pictureBox1.Location.Y + moveY;
                pictureBox1.Location = new Point(x, y);
                mouseDownPoint.X = Cursor.Position.X;
                mouseDownPoint.Y = Cursor.Position.Y;
            }
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            panel1.Focus(); //鼠标不在picturebox上时焦点给别的控件,此时无法缩放
        }

        //实现锚点缩放(以鼠标所指位置为中心缩放);
        //步骤:
        //①先改picturebox长宽,长宽改变量一样;
        //②获取缩放后picturebox中实际显示图像的长宽,这里长宽是不一样的;
        //③将picturebox的长宽设置为显示图像的长宽;
        //④补偿picturebox因缩放产生的位移,实现锚点缩放。
        //注释:为啥要②③步?由于zoom模式的机制,把picturebox背景设为黑就知道为啥了。
        //这里需要获取zoom模式下picturebox所显示图像的大小信息,添加 using System.Reflection;
        private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
        {
            int x = e.Location.X;
            int y = e.Location.Y;
            int ow = pictureBox1.Width;
            int oh = pictureBox1.Height;
            int VX, VY; //因缩放产生的位移矢量
            //第①步
            if (e.Delta > 0) //放大
            {

                pictureBox1.Width += zoomStep;
                pictureBox1.Height += zoomStep;
            }
            else if (e.Delta < 0) //缩小
            {
                //防止一直缩成负值
                if (pictureBox1.Width < 100)
                {
                    return;
                }
                pictureBox1.Width -= zoomStep;
                pictureBox1.Height -= zoomStep;
            }
            //第②步和第③步方法体最好在每次加载新图片的时候都执行一下(原因参考为啥要执行②,③步)
            pictureBoxImgage();
            //第④步,求因缩放产生的位移,进行补偿,实现锚点缩放的效果
            VX = (int)((double)x * (ow - pictureBox1.Width) / ow);
            VY = (int)((double)y * (oh - pictureBox1.Height) / oh);
            pictureBox1.Location = new Point(pictureBox1.Location.X + VX, pictureBox1.Location.Y + VY);
        }
        /// <summary>
        /// 第②步和第③步方法体
        /// </summary>
        public void pictureBoxImgage()
        {
            //第②步
            PropertyInfo pInfo = pictureBox1.GetType().GetProperty("ImageRectangle", BindingFlags.Instance |
            BindingFlags.NonPublic);
            Rectangle rect = (Rectangle)pInfo.GetValue(pictureBox1, null);
            //第③步
            pictureBox1.Width = rect.Width;
            pictureBox1.Height = rect.Height;
        }
        //加这个使图片缩小效果更流畅
        //防止界面闪烁
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        }
    }
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值