文中部分信息来源于网络。
前一段时间,笔者写程序的时候需要用c#实现一个用鼠标将图片放大缩小并且用鼠标拖动、平移图片的功能,在网上找了很多的资料,最终经过资料的整合得出了如下的解决方案。
正文:
实现图片放大缩小的方法很多,对于这个问题,笔者选用的方法是
1.将picturebox上的显示属性image设置为所要操作的图片(可通过在pixcturebox上点击鼠标右键,找到属性选项,在picturebox属性中找到image进行操作)并将sizemode属性设为stretchimage(延伸图像,这样picturebox里的图片会随着picturebox大小尺寸的改变而改变)通过改变picturebox的大小尺寸,同时来放大缩小图片。
2.将picturebox放置在容器控件panel上,并点击panel右上角的小三角,将他停靠在父容器中,将panel的autoscroll属性设置为true,这样就可以在panel中通过横竖滚动条方便的查看放大或缩小后的picturebox。
对于通过鼠标滚轮来放大缩小图片,由于c#中系统没有自带鼠标滑轮事件,所以需要我们自己定义一个鼠标滑轮事件mousewheel,具体如下:
private void panel1_MouseWheel(object sender, MouseEventArgs e)
{
float fZoomFactor = 1.2f; // 缩放因子
int iOriginCentorX=(this.panel1.Width/2-this.pictureBox1.Left); //缩放前
int iOriginCentorY=(this.panel1.Height/2-this.pictureBox1.Top);
*//防止无限制的缩放*
if ((this.pictureBox1.Width < 400 && e.Delta < 0) || (this.pictureBox1.Width > 22000 && e.Delta > 0))
return;
if(e.Delta>0)//判断放大还是缩小
{
//缩放后的picture box的大小。
this.pictureBox1.Width = (int)(fZoomFactor * this.pictureBox1.Width);
this.pictureBox1.Height = (int)(fZoomFactor * this.pictureBox1.Height);
//缩放后的中心点距离picture box左上角的距离。
int iNewCentorX=(int)(iOriginCentorX*fZoomFactor);
int iNewCentorY=(int)(iOriginCentorY*fZoomFactor);
//缩放后的滚轮的位置。
this.panel1.AutoScrollPosition = new Point((int)(iNewCentorX - this.panel1.Width / 2),
(int)(iNewCentorY - this.panel1.Height / 2 + e.Delta));
}
else
{
this.pictureBox1.Width = (int)(this.pictureBox1.Width / fZoomFactor);
this.pictureBox1.Height = (int)(this.pictureBox1.Height / fZoomFactor);
int iNewCentorX = (int)(iOriginCentorX / fZoomFactor);
int iNewCentorY = (int)(iOriginCentorY / fZoomFactor);
this.panel1.AutoScrollPosition = new Point((int)(iNewCentorX - this.panel1.Width / 2),
(int)(iNewCentorY - this.panel1.Height / 2 + e.Delta));
}
}
之后在窗口的Designer.cs中的panel下添加
this.panel1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseWheel);
对mouseweel进行注册,这样在窗体进行初始化时此事件就能被注册添加上,从而对它进行使用。
对于图片的放大缩小,此方法主要是从放大缩小picturebox的大小进而实现放大缩小picturebox中图片的角度实现的。
对于平移图片 主要通过MouseDown、MouseMove、MouseUp这三个事件来实现的。
1.MouseDown记录鼠标点击的位置
2.MouseMove记录鼠标点下后移动的距离,并移动picturebox的位置
3. MouseUp 结束移动
具体代码如下:
1. MouseDown
private bool IsMouseInPanel()//判断鼠标是否超出panel1
{
if (this.panel1.Left < PointToClient(Cursor.Position).X
&& PointToClient(Cursor.Position).X < this.panel1.Left + this.panel1.Width
&& this.panel1.Top < PointToClient(Cursor.Position).Y
&& PointToClient(Cursor.Position).Y < this.panel1.Top + this.panel1.Height)
{
return true;
}
else
{
return false;
}
}
Point mouseDownPoint;
bool isSelected;定义全局变量 记录鼠标是否已点击且未释放
private void pictureBox1_MouseDown_1(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mouseDownPoint.X = Cursor.Position.X; //注:全局变量mouseDownPoint前面已定义为Point类型
mouseDownPoint.Y = Cursor.Position.Y;
isSelected = true;
}
}
2.MouseMove
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
//if ((Cursor.Position.X - mouseDownPoint.X) * 3 > 200 || (Cursor.Position.Y - mouseDownPoint.Y) * 3 > 200)
//return;
if (isSelected && IsMouseInPanel())
{
if (this.panel1.VerticalScroll.Value - (Cursor.Position.X - mouseDownPoint.X) > 0
&& this.panel1.VerticalScroll.Value - (Cursor.Position.X - mouseDownPoint.X) < this.panel1.VerticalScroll.Maximum
&& this.panel1.HorizontalScroll.Value - (Cursor.Position.Y - mouseDownPoint.Y) > 0
&& this.panel1.HorizontalScroll.Value - (Cursor.Position.Y - mouseDownPoint.Y) < this.panel1.HorizontalScroll.Maximum)
{
this.panel1.VerticalScroll.Value = Math.Abs(this.panel1.VerticalScroll.Value - (Cursor.Position.Y - mouseDownPoint.Y));
this.panel1.HorizontalScroll.Value =Math.Abs( this.panel1.HorizontalScroll.Value - (Cursor.Position.X - mouseDownPoint.X));
mouseDownPoint.X = Cursor.Position.X;
mouseDownPoint.Y = Cursor.Position.Y;
}
}
}
3.MouseUp
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
isSelected = false;
}
到此通过鼠标放大、缩小、移动图片的功能就可以实现了。
对于GDI画图:可以将画板申请为pixcturebox的image,在image上绘图。
Graphics g = Graphics.FromImage(this.pictureBox1.Image);
这样所绘的图像即可随着picturebox的放大缩小、平移而移动、放大缩小。
此方法经笔者验证可以实现通过鼠标放大、缩小、平移图片的功能,大家在使用此方法中,如果遇到了什么问题可以私信我。如果有用词不准确,说的不对的地方,欢迎大家指正。