主要优化:
代码简洁化
图片缩小效果更顺畅
窗体后台代码如下:
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;
}
}
}
}