簡體   English   中英

C#WindowsForms PictureBox:控件坐標和圖像中像素位置之間的轉換

[英]C# WindowsForms PictureBox: Transformation between control coordinates and pixel position in image

我有一個帶有PictureBox的控件。 PictureBox顯示圖像(至少在這種情況下,在“縮放”模式下)。 我需要做兩種事情:

  • 用鼠標單擊,找出我擊中圖像的哪個像素
  • 在圖片的給定列上的PictureBox上繪制一條垂直線。

顯然,我需要在控制坐標和圖像中像素的(行,列)之間進行某種坐標轉換。 我可能找到的第一個(www.codeproject.com/Articles/20923/Mouse-Position-over-Image-in-a-PictureBox),反之則不然。 有任何想法嗎?

我可以建議一個“解決方法”:您不要在PictureBox上繪制線條等,而是使用其Graphics在位圖本身上繪制。 然后,您只能使用圖像坐標(行,列),而無需從控件轉換為圖像。 正如您提到的,另一種方法(從鼠標單擊到行和列)已解決並可以使用。

經過幾次嘗試在位圖上而不是在包含PictureBox上繪制圖形元素,我發現這種方法比較笨拙:它帶來的問題多於解決的方法。 我返回了TaW的建議( 此發布功能SetImageScale(PictureBox pbox, out RectangleF rectImage, out float zoom) 。)

如果您知道rectImage矩形( ImgArea在TAW的代碼),既轉換(到控件的坐標和圖像的列和行是再簡單:

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

這些功能已經過測試,似乎可以完成。

請記住 :僅當PictureBox處於“ Zoom模式時,這些轉換才有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM