2017-06-15 74 views
1

这个问题之前被问过,但既然它不起作用,我缺乏声望点(我试着评论问题,但我不能),我不得不再次提出这个问题。如何放大c#中的picturebox中的一个点?

这是以前问的问题的链接; 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

也许你没有添加'pictureBox1_Paint'方法为你的'pictureBox1.Paint'事件的处理程序? – Pikoh

+0

感谢您的回复Pikoh。我怎么做到这一点?如果你说添加油漆选项(从属性/事件)作为'pictureBox1_Paint',我做到了。 – Quanthema

回答

2

您引用的答案不可行。我不知道为什么它被接受,也没有增加投票。除了在过去的某个时候,显然也是它的投票。我不知道我在想什么。

无论如何,该代码存在一些问题:

  1. 它使用鼠标坐标直接传递,而不是把它们转换成坐标系统PictureBox控制。传递给OnMouseWheel()方法的坐标是相对于Form本身的,所以只有当PictureBox左上角与Form的左上角重合时才会起作用。
  2. 更成问题,代码被完全滥用Matrix.Scale()方法,传递其似乎旨在是对比例的增量,而实际上Scale()方法接受用于规模因子的值。这有两个含义:
    • 传递一个负值是错误的,因为负值翻转的坐标系统,而不是缩小规模,
    • 传递的增量值是错误的,因为传递的值会乘以当前的缩放比例以获得新的缩放比例。
  3. 还有一个问题是,代码以错误的顺序应用矩阵转换,因为默认顺序是“prepend”,而不是“append”(我发现后者更自然,但我认为有一些理由是那些专门研究矩阵数学的人解释了为什么默认是前者)。

还有一个相对较小的问题,即使忽略了上述情况,允许用户任意调整比例因子最终会导致超出范围的值。代码将规模限制在合理范围内会更好。

这里是你的代码的一个版本,修改,以便它解决了所有这些问题:

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(); 
    } 
} 

有了这个代码,你会发现,无论你在哪里调整鼠标滚轮之前,请将鼠标,渲染的图像将会缩放,同时将鼠标下方的点固定到位。


注:

我看了看一些堆栈溢出类似的问题,有一些可能还对你有用。在我看来,一些答案会让事情变得复杂,但所有的都应该起作用。请参阅:

Zoom To Point Not Working As Expected
Zoom in on a fixed point using matrices
Zooming graphics without scrolling

+0

非常感谢你。这样可行!! – Quanthema