如何从PictureBox获取真实图像像素点x,y [英] How to get real image pixel point x,y from PictureBox

查看:136
本文介绍了如何从PictureBox获取真实图像像素点x,y的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 pictureBox2 并且它设置为 zoom,我试图找出如何通过 <在图像上获得真实的 x,y 像素位置pictureBox2 上的 code>Mouse.Click.但我尝试了我知道的 3 个可能的想法:没有/有 PointToClient,PointToScreen 但我永远做对了.

I have a pictureBox2 and it is set to zoom, I am trying to find out how to to get a real x,y pixel location on the image by Mouse.Click on pictureBox2. but I tried 3 possible ideas I knew of: without/with PointToClient,PointToScreen but I can never get it right.

private void pictureBox2_Click(object sender, EventArgs e)
{
     MouseEventArgs me = (MouseEventArgs)e;
    txtpictureHeight.Text =( 
        (OriginalImage.GetImageHeight()*me.Location.Y)/ pictureBox2.Image.Height).ToString();
    txtpictureWidth.Text = ( 
        (OriginalImage.GetImageWidth()* me.Location.X)/ pictureBox2.Image.Width).ToString();
}

一定有一些我需要注意的因素,所以我想使用上面的双重结果,然后我关闭了,但是我的测试图像(1371x2221)的高度仍然有 80 像素.当我使用 Zoom 时,我的 pictureBox2

There must be some factor I need to take care of so I thought to use double result from above and I get closed but there is still 80px off for the height on my test image (1371x2221). As I use Zoom so there are 2 extra spaces on my pictureBox2

推荐答案

注意,当 SizeMode 设置为 Zoom 时,PictureBox 保持方面比例,并使图像居中,因此除了计算调整后的坐标外,您还必须考虑填充.

Note that with SizeMode set to Zoom, the PictureBox keeps aspect ratio, and centers the image, so on top of calculating the adjusted coordinates, you also have to take padding into account.

我的建议,不要使用 Click 事件;它旨在检测按钮点击,而不是实际处理鼠标与对象的交互.改用 MouseDown.

My advice, don't use the Click event; it is meant to detect button clicks, not to actually process interaction of the mouse with an object. Use MouseDown instead.

我们需要做的第一件事是获取原始图像的宽度和高度.正如我在评论中指出的,这只是 PictureBoxImage 属性内的对象.

The first thing we need to do is get the width and height of the original image. As I noted in my comment, this is simply the object inside the Image property of the PictureBox.

接下来,我们需要缩放图像的尺寸和位置.为此,我们可以从 PictureBoxClientRectangle 的维度开始.将这些除以图像宽度和高度,您将获得水平和垂直缩放值.如果将 SizeMode 设置为 StretchImage,这就是我们所需要的,但是由于纵横比是守恒的,您需要两个值中最小的一个才能获得实际的缩放系数.

Next, we need the dimensions and location of the zoomed image. For that, we can start from the dimensions of the ClientRectangle of the PictureBox. Divide those by the image width and height and you'll get the horizontal and vertical zoom values. If the SizeMode would be set to StretchImage, that'd be all we need, but since aspect ratio is conserved, you need the smallest of the two values to have the actual zoom factor.

一旦我们得到它,将原始宽度和高度乘以这个缩放系数以获得缩放后的宽度和高度,然后从实际的 ClientRectangle 尺寸中减去它并将其除以二以获得填充对于两个维度.这当然可以通过检查使用两个可能的缩放因子中的哪一个来简化,并且只计算另一个的填充,因为使用缩放因子的维度显然具有 0 填充.

Once we got that, multiply the original width and height by this zoom factor to get the zoomed width and height, then subtract that from the actual ClientRectangle dimensions and divide it by two to get the padding for both dimensions. This can of course be simplified by checking which of the two possible zoom factors is used, and only calculating the padding for the other one, since the dimension of which the zoom factor was used obviously has 0 padding.

现在您获得了填充和缩放系数,剩下的很简单:从鼠标坐标中减去填充值,然后将两个结果除以缩放系数.

Now you got the padding and zoom factor, the rest is simple: subtract the padding values from the mouse coordinates, and then divide both results by the zoom factor.

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    // Default check: left mouse button only
    if (e.Button == MouseButtons.Left)
        ShowCoords(e.X, e.Y);
}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    // Allows dragging to also update the coords. Checking the button
    // on a MouseMove is an easy way to detect click dragging.
    if (e.Button == MouseButtons.Left)
        ShowCoords(e.X, e.Y);
}

private void ShowCoords(Int32 mouseX, Int32 mouseY)
{
    Int32 realW = pictureBox1.Image.Width;
    Int32 realH = pictureBox1.Image.Height;
    Int32 currentW = pictureBox1.ClientRectangle.Width;
    Int32 currentH = pictureBox1.ClientRectangle.Height;
    Double zoomW = (currentW / (Double)realW);
    Double zoomH = (currentH / (Double)realH);
    Double zoomActual = Math.Min(zoomW, zoomH);
    Double padX = zoomActual == zoomW ? 0 : (currentW - (zoomActual * realW)) / 2;
    Double padY = zoomActual == zoomH ? 0 : (currentH - (zoomActual * realH)) / 2;

    Int32 realX = (Int32)((mouseX - padX) / zoomActual);
    Int32 realY = (Int32)((mouseY - padY) / zoomActual);
    lblPosXval.Text = realX < 0 || realX > realW ? "-" : realX.ToString();
    lblPosYVal.Text = realY < 0 || realY > realH ? "-" : realY.ToString();
}

注意,我在这里使用了清晰的像素缩放来更好地显示效果.这是一个小技巧,您可以通过子类化 PictureBox 并覆盖其 OnPaint 方法来调整 PaintEventArgs 中的 Graphics 对象code> 对象并将其 InterpolationMode 设置为 NearestNeighbor(也建议将 PixelOffsetMode 设置为 Half;有一个错误其中锐度缩放会移动半个像素除非您这样做).然后使用调整后的事件参数对象调用 base.OnPaint().

Note, I used sharp pixel zoom here to better show the effect. It's a little trick you can do by subclassing PictureBox and overriding its OnPaint method, to adjust the Graphics object from the PaintEventArgs object and set its InterpolationMode to NearestNeighbor (It's also advised to set PixelOffsetMode to Half; there's a bug where sharp zoom is shifted half a pixel unless you do that). Then you call base.OnPaint() with that adjusted event args object.

我还在此处添加了更多信息,但这只是您可以从像素坐标计算过程的中间值中获得的所有信息.

I also added some more info on it here, but that's all just stuff you can get from the in-between values of the pixel coordinates calculation process anyway.

这篇关于如何从PictureBox获取真实图像像素点x,y的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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