我应该如何从屏幕空间坐标转换为 WinForms PictureBox 中的图像空间坐标?

Posted

技术标签:

【中文标题】我应该如何从屏幕空间坐标转换为 WinForms PictureBox 中的图像空间坐标?【英文标题】:How should I translate from screen space coordinates to image space coordinates in a WinForms PictureBox? 【发布时间】:2010-09-05 09:25:08 【问题描述】:

我有一个在 Windows 窗体 PictureBox 控件中显示图像的应用程序。控件的SizeMode 设置为Zoom,这样PictureBox 中包含的图像无论PictureBox 的尺寸如何都将以正确的方式显示。

这对于应用程序的视觉外观非常有用,因为您可以根据需要调整窗口大小,并且始终以最适合的方式显示图像。不幸的是,我还需要处理图片框上的鼠标点击事件,并且需要能够从屏幕空间坐标转换为图像空间坐标。

看起来从屏幕空间转换到控制空间很容易,但是我没有看到任何明显的从控制空间转换到图像空间的方法(即图片中已缩放的源图像中的像素坐标框)。

有没有一种简单的方法可以做到这一点,或者我应该复制他们在内部使用的缩放数学来定位图像并自己进行翻译?

【问题讨论】:

【参考方案1】:

我最终只是手动实现了翻译。代码还不错,但确实让我希望他们直接为它提供支持。我可以看到这种方法在很多不同的情况下都很有用。

我猜这就是他们添加扩展方法的原因:)

在伪代码中:

// Recompute the image scaling the zoom mode uses to fit the image on screen
imageScale ::= min(pictureBox.width / image.width, pictureBox.height / image.height)

scaledWidth  ::= image.width * imageScale
scaledHeight ::= image.height * imageScale

// Compute the offset of the image to center it in the picture box
imageX ::= (pictureBox.width - scaledWidth) / 2
imageY ::= (pictureBox.height - scaledHeight) / 2

// Test the coordinate in the picture box against the image bounds
if pos.x < imageX or imageX + scaledWidth < pos.x then return null
if pos.y < imageY or imageY + scaledHeight < pos.y then return null

// Compute the normalized (0..1) coordinates in image space
u ::= (pos.x - imageX) / imageScale
v ::= (pos.y - imageY) / imageScale
return (u, v)

要获得图像中的像素位置,您只需乘以实际图像像素尺寸,但归一化坐标允许您解决原始响应者关于逐案解决歧义的观点。

【讨论】:

您好,如果您手头还有您编写的代码示例,那就太好了。【参考方案2】:

根据缩放比例,相对图像像素可以是多个像素中的任意位置。例如,如果图像被显着缩小,像素 2、10 可能代表 2、10 一直到 20、100),因此您必须自己进行数学运算并对任何不准确承担全部责任! :-)

【讨论】:

以上是关于我应该如何从屏幕空间坐标转换为 WinForms PictureBox 中的图像空间坐标?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 2D 世界转换为屏幕坐标 OpenGL

从剪辑空间到屏幕坐标的转换何时发生?

使用正交矩阵将 3D 坐标转换为 2D 屏幕坐标

Unity从深度缓冲重建世界空间位置

Unity Shaderlab-从屏幕空间到世界空间的转换

将坐标从图像转换为屏幕