C# 我应该如何在 WinForms PictureBox 中将屏幕空间坐标转换为图像空间坐标?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How should I translate from screen space coordinates to image space coordinates in a WinForms PictureBox?
提问by fastcall
I have an application that displays an image inside of a Windows Forms PictureBox
control. The SizeMode
of the control is set to Zoom
so that the image contained in the PictureBox
will be displayed in an aspect-correct way regardless of the dimensions of the PictureBox
.
我有一个在 Windows 窗体PictureBox
控件中显示图像的应用程序。的SizeMode
控制被设定为Zoom
使得图像包含在PictureBox
将在一个方面,正确的方式被显示不管尺寸的PictureBox
。
This is great for the visual appearance of the application because you can size the window however you want and the image will always be displayed using its best fit. Unfortunately, I also need to handle mouse click events on the picture box and need to be able to translate from screen-space coordinates to image-space coordinates.
这对于应用程序的视觉外观非常有用,因为您可以根据需要调整窗口大小,并且图像将始终以其最佳尺寸显示。不幸的是,我还需要处理图片框上的鼠标单击事件,并且需要能够从屏幕空间坐标转换为图像空间坐标。
It looks like it's easy to translate from screen space to control space, but I don't see any obvious way to translate from control space to image space (i.e. the pixel coordinate in the source image that has been scaled in the picture box).
看起来从屏幕空间转换到控制空间很容易,但我没有看到任何明显的从控制空间转换到图像空间的方法(即在图片框中缩放的源图像中的像素坐标)。
Is there an easy way to do this, or should I just duplicate the scaling math that they're using internally to position the image and do the translation myself?
有没有一种简单的方法可以做到这一点,或者我应该复制他们在内部使用的缩放数学来定位图像并自己进行翻译?
采纳答案by tags2k
Depending on the scaling, the relative image pixel could be anywhere in a number of pixels. For example, if the image is scaled down significantly, pixel 2, 10 could represent 2, 10 all the way up to 20, 100), so you'll have to do the math yourself and take full responsibility for any inaccuracies! :-)
根据缩放比例,相对图像像素可以在多个像素中的任何位置。例如,如果图像被显着缩小,像素 2、10 可能代表 2、10 一直到 20、100),因此您必须自己进行数学计算并对任何不准确之处承担全部责任!:-)
回答by fastcall
I wound up just implementing the translation manually. The code's not too bad, but it did leave me wishing that they provided support for it directly. I could see such a method being useful in a lot of different circumstances.
我最终只是手动实施翻译。代码还不错,但确实让我希望他们直接为其提供支持。我可以看到这种方法在许多不同的情况下都很有用。
I guess that's why they added extension methods :)
我想这就是他们添加扩展方法的原因:)
In pseudocode:
在伪代码中:
// 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)
To get the pixel position in the image, you'd just multiply by the actual image pixel dimensions, but the normalized coordinates allow you to address the original responder's point about resolving ambiguity on a case-by-case basis.
要获得图像中的像素位置,您只需乘以实际图像像素尺寸,但标准化坐标允许您解决原始响应者关于逐案解决歧义的观点。