这个问题之前被问过,但由于它不起作用而我的声誉不足(我试着评论但我不能)我不得不再次提出这个问题。
这是之前提出的问题的联系; How to zoom at a point in picturebox
我使用了链接中显示的代码,但是当我运行它时,点或形状消失。
这是我的代码;
public partial class Form1 : Form
{
private Matrix transform = new Matrix();
private double m_dZoomscale = 1.0;
public static double s_dScrollValue = .1;
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Transform = transform;
Pen mypen = new Pen(Color.Red,5);
Rectangle rect = new Rectangle(10, 10, 30, 30);
e.Graphics.DrawRectangle(mypen, rect);
}
protected override void OnMouseWheel(MouseEventArgs mea)
{
pictureBox1.Focus();
if (pictureBox1.Focused == true && mea.Delta != 0)
{
ZoomScroll(mea.Location, mea.Delta > 0);
}
}
private void ZoomScroll(Point location, bool zoomIn)
{
transform.Translate(-location.X, -location.Y);
if (zoomIn)
transform.Scale((float)s_dScrollValue, (float)s_dScrollValue);
else
transform.Scale((float)-s_dScrollValue, (float)-s_dScrollValue);
transform.Translate(location.X, location.Y);
pictureBox1.Invalidate();
}
答案 0 :(得分:3)
您所引用的答案无法奏效。我不知道为什么它被接受,也没有被投票。除了在过去的某个时间,我显然也投票了。我不知道自己在想什么。
无论如何,该代码存在一些问题:
PictureBox
控件的坐标系。传递给OnMouseWheel()
方法的坐标相对于Form
本身,因此仅当PictureBox
左上角与Form
左上角重合时角落会起作用。Matrix.Scale()
方法,为规模传递了似乎是 delta 的值,实际上是Scale()
方法接受比例的因子。这有两个含义:
还有一个相对较小的问题,即使忽略了上述内容,允许用户任意调整比例因子,最终也会导致超出范围的值。代码将规模限制在合理的范围内会更好。
以下是您的代码版本,经过修改后可以解决所有这些问题:
private Matrix transform = new Matrix();
private float m_dZoomscale = 1.0f;
public const float s_dScrollValue = 0.1f;
public Form1()
{
InitializeComponent();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Transform = transform;
Pen mypen = new Pen(Color.Red, 5);
Rectangle rect = new Rectangle(10, 10, 30, 30);
e.Graphics.DrawRectangle(mypen, rect);
}
protected override void OnMouseWheel(MouseEventArgs mea)
{
pictureBox1.Focus();
if (pictureBox1.Focused == true && mea.Delta != 0)
{
// Map the Form-centric mouse location to the PictureBox client coordinate system
Point pictureBoxPoint = pictureBox1.PointToClient(this.PointToScreen(mea.Location));
ZoomScroll(pictureBoxPoint, mea.Delta > 0);
}
}
private void ZoomScroll(Point location, bool zoomIn)
{
// Figure out what the new scale will be. Ensure the scale factor remains between
// 1% and 1000%
float newScale = Math.Min(Math.Max(m_dZoomscale + (zoomIn ? s_dScrollValue : -s_dScrollValue), 0.1f), 10);
if (newScale != m_dZoomscale)
{
float adjust = newScale / m_dZoomscale;
m_dZoomscale = newScale;
// Translate mouse point to origin
transform.Translate(-location.X, -location.Y, MatrixOrder.Append);
// Scale view
transform.Scale(adjust, adjust, MatrixOrder.Append);
// Translate origin back to original mouse point.
transform.Translate(location.X, location.Y, MatrixOrder.Append);
pictureBox1.Invalidate();
}
}
使用此代码,您会发现无论您在调整鼠标滚轮之前放置鼠标的位置,渲染图像都会缩放,同时保持鼠标下方的点固定到位。
注意:强>
我看了一下Stack Overflow上的一些类似问题,还有一些可能对你有用。在我看来,有些答案过于复杂,但一切都应该有效。参见:
Zoom To Point Not Working As Expected
Zoom in on a fixed point using matrices
Zooming graphics without scrolling