缩放后重新计算面板 AutoScrollPosition [英] Recompute Panel AutoScrollPosition after zoom

查看:17
本文介绍了缩放后重新计算面板 AutoScrollPosition的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

解决方案

典型的三种缩放类型:

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

我假设典型设置:PictureBox 设置为 SizeMode=Zoom 嵌套Panel 中,AutoScroll=true 和缩放,注意保持 ImagePictureBox 纵横比 相等.

让我们从介绍术语开始:

  • 有一个 Image 我们称之为 bitmap
  • 它由PictureBox显示;我们称之为画布...
  • ...嵌套在我们称为frame
  • Panel

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

对于 1) 它是 框架 的中心,对于 2) 它是鼠标位置,对于 3) 它是矩形的中心.

在缩放之前我们计算旧缩放比例中的固定点,画布,最后是位图中的固定点.

缩放后,我们计算新的缩放比例画布中的新固定点.最后,我们用它来移动画布,将固定的画布点带到固定的帧点.><小时>

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

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

private void zoom_Click(object sender, EventArgs e){图片框画布 = 图片框 1;面板框架 = panel1;//根据按钮设置新的缩放级别浮动缩放 = 发送者 == btn_ZoomIn ?2f:0.5f;//计算旧比率:浮动比例 = 1f * canvas.ClientSize.Width/canvas.Image.Width;//计算帧固定像素:Point fFix = new Point(frame.Width/2, frame.Height/2);//计算画布固定像素:Point cFix = new Point(-canvas.Left + fFix.X, -canvas.Top + fFix.Y);//计算位图固定像素:Point iFix = new Point((int)(cFix.X/ratio),(int)( cFix.Y/ratio));//做缩放canvas.Size = new Size( (int)(canvas.Width * zoom), (int)(canvas.Height * zoom) );//计算新的比率:float ratio2 = 1f * canvas.ClientSize.Width/canvas.Image.Width;//计算新的画布固定像素:Point cFix2 = new Point((int)(iFix.X * ratio2),(int)( iFix.Y * ratio2));//移动画布:canvas.Location = new Point(-cFix2.X + fFix.X, -cFix2.Y + fFix.Y);}

<小时>

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

Have C# forms application with PictureBox embedded in Panel, to take advantage of Panel AutoScroll as suggested in other posts when image and thus PictureBox need to be scrolled horizontally or vertically. Want to zoom the image and recompute AutoScrollPosition to keep same Point visible after zooming. Can double size of PictureBox, then recopy source image, accomplishing zoom. But AutoScrollPosition remains unchanged, thus what was visible before zoom has moved off screen. How to recompute AutoScrollPosition to keep image focus after zoom?

解决方案

There are three typical types of zooming:

  1. zoom into the center, triggered by zoom buttons
  2. zoom into the mouse position, triggered by clicking or scroll-wheeling
  3. zoom into a rectangle, by drawing a rectangle

I assume the typical setup: A PictureBox set to SizeMode=Zoom nested in a Panel with AutoScroll=true and zooming that takes care to keep the aspect ratios of Image and PictureBox equal.

Let's start by introducing terminology:

  • There is an Image we call bitmap and
  • it is displayed by a PictureBox; let's call it canvas..
  • .. which is nested in a Panel we call frame

User-friendly zooming needs a fixed point, that is a point that shall stay put.

For 1) it is the center of the frame, for 2) it is the mouse location and for 3) it is the center of the rectangle.

Before zooming we calculate the old zoom ratio, the fixed point in the frame, the fixed point in the canvas and finally the fixed point in the bitmap.

After zoming we calculate the new zoom ratio and the new fixed point in the canvas. Finally we use it to move the canvas to bring the fixed canvas point to the fixed frame point.


Here is an example for zooming into the (current) center; it is a common click event for two buttons and it only doubles and halves the zoom ratio.

Much finer grained factors are of course simple to implement; even better is a fixed list of zoom levels, like Photoshop has!

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


Note that while one can try to restore the relative AutoScrollValues this is not only hard, because their values are a little quirky but it is also won't be adaptable to the other zoom types.

这篇关于缩放后重新计算面板 AutoScrollPosition的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆