缩放后重新计算面板滚动位置

2023-12-07

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


缩放有三种典型类型:

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

我假设典型的设置:APictureBox set to SizeMode=Zoom nested in a Panel with AutoScroll=true和缩放,注意保持纵横比 of Image and PictureBox equal.

我们首先介绍一下术语:

  • 有一个Image我们称之为bitmap and
  • 它由一个显示PictureBox;我们就这样称呼它吧canvas..
  • ..嵌套在Panel我们称之为frame

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

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

在缩放之前我们计算旧的变焦比,中的固定点frame, 中的不动点canvas最后是固定点bitmap.

缩放后我们计算新的变焦比和新的固定点canvas。最后我们用它来移动canvas带来固定的画布点到固定的框架点.


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

当然,更细粒度的因素很容易实现;更好的是固定的缩放级别列表,就像 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);
}

Note虽然人们可以尝试挽回亲人AutoScrollValues这不仅很难,因为它们的值有点奇怪,而且它也无法适应其他缩放类型。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

缩放后重新计算面板滚动位置 的相关文章

随机推荐

  • 为什么不调用复制构造函数?

    class MyClass public MyClass MyClass x 0 y 0 default constructor MyClass int X int Y x X y Y user defined constructor My
  • lex 和 yacc(符号表生成)

    我对编译器设计中的 lex 和 yacc 很陌生 我想知道符号表是在哪个阶段 词汇 句法或任何其他阶段 以及如何生成的 我可以简要描述一下 y output 文件 该文件是通过向 yacc 提供 v 选项生成的 我试图研究它 但没有得到太多
  • 编写 thunk 来验证 SysV ABI 合规性

    The SysV ABI定义 Linux 的 C 级和汇编调用约定 我想编写一个通用的 thunk 来验证函数是否满足被调用者保留寄存器的 ABI 限制 并且 可能 尝试返回一个值 So given a target function li
  • 我正在尝试创建一个存储过程来创建登录名和数据库用户?

    我正在使用 SQL Server 开发 C 应用程序 并且想调用存储过程来创建登录名和用户 我正在寻找最简单的方法来做到这一点 只是默认的东西 但有用户名和密码 登录旁边的创建有红色下划线 但我觉得我的登录没问题 如果我遗漏了什么 请告诉我
  • 如何随机选择对象密钥?

    我有以下代码 namedarray India New Delhi namedarray Australia Canberra namedarray Indonasia Jakarta namedarray Iran Tehrani nam
  • python Fabric 多个命令

    我试图了解 Fabric 如何在一台机器上使用多个命令 我需要在每台主机 数千台主机 上运行多个命令 并且想知道什么是最好的 使用多次运行 res 1 run command 1 res 2 run command 2 res n run
  • 使用 Google 服务帐户模拟用户列表

    根据文档 Google Apps 域管理员可以向服务帐户授予域范围内的权限 以代表域中的用户访问用户数据 我的轻描淡写是 这赋予了服务帐户访问数据的权限全部用户域内 有没有办法限制哪些用户服务帐户有权访问 例如 使用 Google Cale
  • 即使在同步期间也会执行自定义 gradle 任务

    所以我确信这是一个非常愚蠢的错误 但我需要你的帮助 因为我不是 gradle 专家 TASK 从文件中读取 versionCode 添加 1 并将其保存回来 task executeOrderSixtySix def versionProp
  • 第二次调用回调时 JVM 崩溃

    我使用 JNA 调用本机库 我的回调接口 public interface PPAEvent extends Callback void callback int eventCode int opCode String Data 我有一个回
  • firebase.auth.GoogleAuthProvider 不是构造函数

    我正在尝试在 Vue 框架中使用 firebase 来使用 google 标志 我不知道这是什么错误 任何人都可以帮助我解决这个问题 vue runtime esm js 2b0e 1888 TypeError firebase js WE
  • swig 无法找到 openssl conf

    尝试安装 m2crypto 并出现这些错误 有人可以帮忙吗 SWIG evp i 12 Error Unable to find openssl opensslconf h SWIG ec i 7 Error Unable to find
  • 将不同的列传递给函数内的 aes

    我正在尝试编写一个函数 该函数使用不同的 aes 参数调用 ggplot hmean lt function data column Label label ggplot data aes column geom histogram fac
  • HTML 中的空脚本标签是怎么回事? [复制]

    这个问题在这里已经有答案了 要在 HTML 页面中包含外部 JavaScript 文件 您可以使用以下命令 该标签的主体是空的 但我必须输入字符串script两次 为什么 HTML 中没有 XML 风格的隐式结束标记 如下所示 如果它是有效
  • 如何在 RichTextBox 中设置内嵌图像垂直居中

    我正在开发 WPF 我在 RichTextBox 中显示 RichText 数据 因为它采用了 WindowsFormHost 在其中我采用 WinForm RichTextBox 来显示具有图像 文本的 RichTextData 但是 当
  • Jenkins 显示 JMeter 脚本失败,即使脚本实际上通过了

    I have my jmeter script running from a jenkins job but it is always reporting it as failed even though the script actual
  • 如何使用java和PDFBox从PDF中获取字符的Unicode

    我正在使用 Apache PDFBox 和 Java 来解析 PDF 并从中获取所有信息 提取文本仅适用于英语 对于其他语言 我只得到一些特殊字符 例如 提取阿拉伯字符 将在打印时给出字符串 当我将计算机的 区域和语言 从英语更改为阿拉伯语
  • takeWhileInclusive 的这种实现安全吗?

    我发现以下包容性的实现takeWhile found here fun
  • Android 7 Genymotion 模拟器上的 Google Play 服务

    我购买了 Genymotion 目的是通过 Android 7 0 和 Google Play 进行模拟 Android 7 0 在 Genymotion 上运行良好 但我无法在其上安装 Google Play Google Play 在
  • 将 NULL 值排序到表末尾

    PostgreSQL 有没有办法对行进行排序NULL字段中的值是否到所选表的末尾 Like SELECT FROM table ORDER BY somevalue PUT NULL TO END NULL values are默认排在最后
  • 缩放后重新计算面板滚动位置

    将 C 表单应用程序与 PictureBox 嵌入面板中 以便在图像和 PictureBox 需要水平或垂直滚动 时利用其他帖子中建议的面板自动滚动 想要缩放图像并重新计算 AutoScrollPosition 以在缩放后保持相同的点可见