2008-08-05 38 views
13

J'ai une application qui affiche une image à l'intérieur d'un contrôle Windows Forms PictureBox. Le SizeMode du contrôle est défini sur Zoom de sorte que l'image contenue dans le PictureBox sera affichée d'une manière correcte d'aspect quelles que soient les dimensions du PictureBox.Comment convertir les coordonnées de l'espace écran en coordonnées de l'espace image dans un PictureFox WinForms?

Ceci est idéal pour l'aspect visuel de l'application, car vous pouvez dimensionner la fenêtre comme vous le souhaitez et l'image sera toujours affichée en utilisant son meilleur ajustement. Malheureusement, je dois aussi gérer les événements de clic de la souris sur la zone d'image et avoir besoin de pouvoir traduire les coordonnées de l'espace de l'écran en coordonnées de l'espace image. Il semble qu'il soit facile de traduire de l'espace écran pour contrôler l'espace, mais je ne vois pas de moyen évident de traduire de l'espace de contrôle à l'espace image (ie la coordonnée de pixel dans l'image source qui a été mise à l'échelle dans le Boîte d'image).

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

Répondre

1

En fonction de la mise à l'échelle, le pixel d'image relatif pourrait être n'importe où dans un certain nombre de pixels. Par exemple, si l'image est considérablement réduite, le pixel 2, 10 pourrait représenter 2, 10 jusqu'à 20, 100), vous devrez donc faire vous-même les calculs et assumer l'entière responsabilité des inexactitudes! :-)

6

Je me suis contenté d'implémenter la traduction manuellement. Le code n'est pas trop mauvais, mais il m'a laissé souhaiter qu'ils fournissent un soutien direct. Je pourrais voir une telle méthode utile dans beaucoup de circonstances différentes.

Je suppose que ce 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 de pixel dans l'image, vous devriez simplement multiplier par les dimensions de pixel d'image réelle, mais les coordonnées normalisées vous permettent de répondre au point de l'intervenant d'origine sur la résolution de l'ambiguïté au cas par cas.

+1

Salut, ce serait génial de voir un échantillon du code que vous avez mis ensemble si vous l'avez toujours à portée de main. –

+1

Bien sûr, je l'ai édité dans ma réponse – fastcall