【问题标题】:Recompute Panel AutoScrollPosition after zoom缩放后重新计算面板 AutoScrollPosition
【发布时间】:2017-12-22 05:52:16
【问题描述】:

在 Panel 中嵌入带有 PictureBox 的 C# 表单应用程序,以便在图像和 PictureBox 需要水平或垂直滚动​​时利用其他帖子中建议的 Panel AutoScroll。想要缩放图像并重新计算 AutoScrollPosition 以在缩放后保持相同的点可见。可以将PictureBox的大小加倍,然后重新复制源图像,完成缩放。但 AutoScrollPosition 保持不变,因此缩放之前可见的内容已移出屏幕。 缩放后如何重新计算 AutoScrollPosition 以保持图像焦点?

【问题讨论】:

  • 我们的邮政编码。

标签: c# winforms autoscroll


【解决方案1】:

有三种典型的缩放类型:

  1. 放大到中心,由缩放按钮触发
  2. 放大鼠标位置,通过点击或滚轮触发
  3. 通过绘制矩形放大矩形

我假设典型设置:将PictureBox 设置为SizeMode=Zoom 嵌套 在带有PanelAutoScroll=true 和注意保持纵横比 的缩放ImagePictureBox 的强>相等

让我们从介绍术语开始:

  • 有一个Image,我们称之为位图
  • 显示为PictureBox;我们称之为 canvas..
  • .. 嵌套在 Panel 中,我们称之为 frame

用户友好的缩放需要一个固定点,这个点应该保持不变。

对于 1) 它是 frame 的中心,对于 2) 它是鼠标位置,对于 3) 它是矩形的中心。

在缩放之前,我们计算旧的缩放比例,中的不动点,中的不动点>canvas,最后是位图中的固定点。

缩放后,我们计算新的缩放比例画布中的新固定点。最后我们用它来移动canvas,将固定的canvas point带到固定的frame point。 p>


这是放大(当前)中心的示例;这是两个按钮的常见点击事件,它只会将缩放比例加倍和减半。

更细粒度的因素当然很容易实现;更好的是一个固定的缩放级别列表,就像 Photoshop 一样!

private void zoom_Click(object sender, EventArgs e)
{
    PictureBox canvas = pictureBox1;
    Panel frame = panel1;

    // Set new zoom level, depending on the button
    float zoom = sender == btn_ZoomIn ? 2f : 0.5f;

    // calculate old ratio:
    float ratio = 1f * canvas.ClientSize.Width / canvas.Image.Width;
    // calculate frame fixed pixel:
    Point fFix = new Point( frame.Width / 2,  frame.Height / 2);
    // calculate the canvas fixed pixel:
    Point cFix =  new Point(-canvas.Left + fFix.X, -canvas.Top + fFix.Y );
    // calculate the bitmap fixed pixel:
    Point iFix = new Point((int)(cFix.X / ratio),(int)( cFix.Y / ratio));

    // do the zoom
    canvas.Size = new Size( (int)(canvas.Width *  zoom), (int)(canvas.Height *  zoom) );

    // calculate new ratio:
    float ratio2 = 1f * canvas.ClientSize.Width / canvas.Image.Width;
    // calculate the new canvas fixed pixel:
    Point cFix2 = new Point((int)(iFix.X * ratio2),(int)( iFix.Y * ratio2));
    // move the canvas:
    canvas.Location = new Point(-cFix2.X + fFix.X, -cFix2.Y + fFix.Y);
}

注意虽然可以尝试恢复相对的AutoScrollValues,但这不仅很难,因为它们的值有点古怪,而且也不适用于其他缩放类型.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-28
    • 1970-01-01
    • 2017-03-11
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    • 1970-01-01
    相关资源
    最近更新 更多