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

我有一个应用程序在Windows窗体 PictureBox 控件中显示图像。控件的 SizeMode 被设置为 Zoom ,以便包含在 PictureBox 中的图像以正确的方式显示,而不管 PictureBox 的尺寸。

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

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

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

0
额外 编辑
意见: 2

2 答案

根据缩放比例,相对图像像素可能在许多像素中的任何位置。例如,如果图像显着缩小,像素2,10可以代表2,10直到20,100),所以您必须自己做数学计算,并对任何不准确情况承担全部责任! :-)

0
额外

我结束了手动执行翻译。代码不是太糟糕,但它确实让我希望他们直接提供对它的支持。我可以看到这种方法在很多不同的情况下都很有用。

我想这就是为什么他们添加扩展方法:)

在伪代码中:

// 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)

为了获得图像中的像素位置,您只需乘以实际的图像像素尺寸,但标准化的坐标可以让您解决原始响应方关于逐个解决歧义问题的观点。

0
额外
当然,我把它编辑成我的回应
额外 作者 fastcall,
嗨,如果您仍然有兴趣,可以看看您放在一起的代码示例。
额外 作者 Kevin Wilson,