c# - Comment convertir des coordonnées d'espace d'écran en coordonnées d'espace d'image dans une PictureBox WinForms?

Translate

J'ai une application qui affiche une image à l'intérieur d'un Windows FormsPictureBoxcontrôle. leSizeModedu contrôle est réglé surZoomafin que l'image contenue dans lePictureBoxs'affichera de manière correcte, quelles que soient les dimensions duPictureBox.

Ceci est idéal pour l'apparence visuelle de l'application car vous pouvez dimensionner la fenêtre comme vous le souhaitez et l'image sera toujours affichée avec son meilleur ajustement. Malheureusement, je dois également gérer les événements de clic de souris sur la zone d'image et je dois être capable de traduire des coordonnées d'espace écran en coordonnées d'espace image.

Il semble qu'il est facile de traduire de l'espace de l'écran à l'espace de contrôle, mais je ne vois aucun moyen évident de traduire de l'espace de contrôle à l'espace image (c'est-à-dire la coordonnée de pixel dans l'image source qui a été mise à l'échelle dans la zone d'image).

Existe-t-il un moyen simple de le faire, ou devrais-je simplement dupliquer les calculs de mise à l'échelle qu'ils utilisent en interne pour positionner l'image et faire la traduction moi-même?

This question and all comments follow the "Attribution Required."

Toutes les réponses

Translate

En fonction de la mise à l'échelle, le pixel d'image relatif peut être n'importe où dans un certain nombre de pixels. Par exemple, si l'image est réduite de manière significative, les pixels 2, 10 pourraient représenter 2, 10 jusqu'à 20, 100), vous devrez donc faire le calcul vous-même et prendre l'entière responsabilité de toute inexactitude! :-)

La source
Translate

J'ai fini par implémenter la traduction manuellement. Le code n'est pas trop mal, mais cela m'a laissé souhaiter qu'ils fournissent un support directement. Je pouvais voir une telle méthode être utile dans de nombreuses circonstances différentes.

Je suppose que c'est pourquoi ils ont ajouté des méthodes d'extension :)

En 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)

Pour obtenir la position des pixels dans l'image, il suffit de multiplier par les dimensions réelles des pixels de l'image, mais les coordonnées normalisées vous permettent d'aborder le point du répondant d'origine sur la résolution de l'ambiguïté au cas par cas.

La source