Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#WindowsForms PictureBox:图像中控制坐标和像素位置之间的转换_C#_Picturebox_Coordinate Transformation - Fatal编程技术网

C#WindowsForms PictureBox:图像中控制坐标和像素位置之间的转换

C#WindowsForms PictureBox:图像中控制坐标和像素位置之间的转换,c#,picturebox,coordinate-transformation,C#,Picturebox,Coordinate Transformation,我有一个控件,里面有一个图片盒。PictureBox显示图像(在缩放模式下,至少在这种特殊情况下)。我需要做两件事: 用鼠标点击,找出我点击的图像像素 在图像中给定列的PictureBox上绘制一条垂直线 显然,我需要在控制坐标和图像中像素的(行、列)之间进行某种坐标变换。我可能已经找到了第一个(www.codeproject.com/Articles/20923/Mouse-Position-over-Image-in-a-PictureBox),但反之亦然。有什么想法吗?我可以建议一种“

我有一个控件,里面有一个图片盒。PictureBox显示图像(在缩放模式下,至少在这种特殊情况下)。我需要做两件事:

  • 用鼠标点击,找出我点击的图像像素
  • 在图像中给定列的PictureBox上绘制一条垂直线

显然,我需要在控制坐标和图像中像素的(行、列)之间进行某种坐标变换。我可能已经找到了第一个(www.codeproject.com/Articles/20923/Mouse-Position-over-Image-in-a-PictureBox),但反之亦然。有什么想法吗?

我可以建议一种“变通方法”:您不在PictureBox上绘制线条等,而是使用位图本身的图形绘制线条等。然后,您可以只使用图像坐标(行、列),而不需要将控件转换为图像。另一种方法(从鼠标单击到行和列),正如您所提到的,已经解决了,并且可以使用。

尝试了几次在位图上而不是在包含PictureBox上绘制图形元素后,我发现这种方法很笨拙:它带来的问题比解决的问题多。我回到了TaW的建议(函数
SetImageScale(PictureBox pbox,out RectangleF rectImage,out float zoom)

如果您知道TaW代码中的
rectImage
矩形(
ImgArea
),则两种转换(到控件坐标以及到图像的列和行)都非常简单:

    /// <summary>
    /// Converts coordinates of a point from the picture box grid into column and row of its image.
    /// </summary>
    /// <param name="pb">The PictureBox.</param>
    /// <param name="ptControl">The point in picture box coordinates (X, Y).</param>
    /// <returns>Point in image coordinates (column, row).</returns>
    private Point ToImageCoordinates(PictureBox pb, Point ptControl)
    {
        if (pb.Image == null)
        {
            return new Point(Int32.MinValue, Int32.MinValue);
        }

        float deltaX    = ptControl.X - rectImage.Left;
        float deltaY    = ptControl.Y - rectImage.Top;

        int column      = (int)(deltaX * (pb.Image.Width / rectImage.Width) + 0.5);
        int row         = (int)(deltaY * (pb.Image.Height / rectImage.Height) + 0.5);

        return new Point(column, row);
    }

    /// <summary>
    /// Converts coordinates of a point from the grid (column, row) into the coordinate system of the picture box.
    /// </summary>
    /// <param name="pb">The PictureBox.</param>
    /// <param name="ptImage">The point in image coordinates (column, row).</param>
    /// <returns>Point in control coordinates (X, Y).</returns>
    private PointF ToControlCoordinates(PictureBox pb, Point ptImage)
    {
        if (pb.Image == null)
        {
            return new Point(Int32.MinValue, Int32.MinValue);
        }

        float deltaX    = ptImage.X * (rectImage.Width / pb.Image.Width);
        float deltaY    = ptImage.Y * (rectImage.Height / pb.Image.Height);

        return new PointF(deltaX + rectImage.Left, deltaY + rectImage.Top);
    }
//
///将点的坐标从图片框栅格转换为其图像的列和行。
/// 
///图片盒。
///图片框坐标(X,Y)中的点。
///图像坐标中的点(列、行)。
专用点到图像坐标(PictureBox pb,点控制)
{
if(pb.Image==null)
{
返回新点(Int32.MinValue,Int32.MinValue);
}
float deltaX=ptControl.X-rectImage.Left;
float deltaY=ptControl.Y-rectImage.Top;
int列=(int)(deltaX*(pb.Image.Width/rectImage.Width)+0.5);
int行=(int)(deltaY*(pb.Image.Height/rectImage.Height)+0.5);
返回新点(列、行);
}
/// 
///将点的坐标从栅格(列、行)转换为图片框的坐标系。
/// 
///图片盒。
///图像坐标中的点(列、行)。
///控制坐标(X,Y)中的点。
专用点F到控制坐标(PictureBox pb,点ptImage)
{
if(pb.Image==null)
{
返回新点(Int32.MinValue,Int32.MinValue);
}
float deltaX=ptImage.X*(rectiimage.Width/pb.Image.Width);
float deltaY=ptImage.Y*(rectiimage.Height/pb.Image.Height);
返回新的点F(deltaX+rectImage.Left,deltaY+rectImage.Top);
}
这些功能已经过测试,似乎做了它们应该做的事情


记住:只有当PictureBox处于
缩放
模式时,这些转换才有效。

应该会有所帮助。谢谢TaW,但它似乎无法解决从控制坐标到图像坐标(行、列)的转换计算问题-如果我误解了,请纠正我。不确定为什么它不会。正如您所看到的,它可以使用鼠标在缩放模式下绘制图像。在获得
ImageArea
矩形后,您可以使用
scalePoint
函数双向转换坐标。代码的其余部分可能与您的问题无关。(今天我想把
SetImageScale
函数重命名为
GetImageScale
,不过:-)嘿,我想我现在就去做谢谢FrancescaY:这可能是一个可行的解决方案!计算一个比另一个更容易吗?TaW:这只是懒惰:现在有一些现成的代码,而且似乎可以工作。反过来说,我必须自己做所有的计算、测试、更正等:如果不是几天,也需要几个小时。我的目标是尽快制作一个工作原型l如果这对你有效,那就好了。(我不知道怎么做)但我给你指出了在两个方向上都有效的工作和准备好的代码。再次感谢你,我注意到了它,并将在(如果)我在一个可靠的实现上工作时看一看。到目前为止,我实现了FrancescaY的建议,它做了需要做的事情。