c# - Hogyan kell lefordítani a képernyőtér-koordinátáktól a képtér-koordinátákká WinForms PictureBox-ban?

original title: "c# - How should I translate from screen space coordinates to image space coordinates in a WinForms PictureBox?"


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.

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?

Van egy alkalmazásom, amely képet jelenít meg a Windows Forms PictureBox vezérlő belsejében. A vezérlés SizeMode beállítása Zoom értékre állítva, hogy a PictureBox-ban lévő kép megjelenjen ...

Ez az összefoglalás a fordítás után. Ha meg szeretné tekinteni a teljes fordítást, kattintson a "fordítás" ikonra

Minden válasz
  • Translate

    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! :-)

  • Translate

    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.