Как мне преобразовать координаты экранного пространства в координаты пространства изображения в WinForms PictureBox?

У меня есть приложение, которое отображает изображение внутри PictureBox элемента управления Windows Forms. SizeMode элемента управления устанавливается в Zoom, так что изображение, содержащееся в PictureBox, будет отображаться с правильным соотношением сторон независимо от размеров PictureBox.

Это отлично подходит для внешнего вида приложения, потому что вы можете изменять размер окна, как хотите, и изображение всегда будет отображаться в наиболее подходящем для него размере. К сожалению, мне также нужно обрабатывать события щелчка мышью в графическом блоке, и мне нужно иметь возможность переводить из координат экранного пространства в координаты пространства изображения.

Похоже, что легко перевести из пространства экрана в пространство управления, но я не вижу очевидного способа перевода из пространства управления в пространство изображения (то есть координаты пикселя в исходном изображении, которое было масштабировано в поле изображения).

Есть ли простой способ сделать это, или я должен просто продублировать математику масштабирования, которую они используют внутри, чтобы расположить изображение и сделать перевод самостоятельно?


person fastcall    schedule 05.08.2008    source источник


Ответы (2)


В зависимости от масштабирования относительный пиксель изображения может находиться в любом месте в нескольких пикселях. Например, если изображение значительно уменьшено, пиксель 2, 10 может представлять 2, 10 вплоть до 20, 100), поэтому вам придется посчитать самостоятельно и взять на себя полную ответственность за любые неточности! :-)

person tags2k    schedule 05.08.2008

Я просто выполнял перевод вручную. Код неплохой, но мне хотелось, чтобы они оказали ему поддержку напрямую. Я видел, что такой метод может быть полезен в самых разных обстоятельствах.

Думаю, поэтому добавили методы расширения :)

В псевдокоде:

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

Чтобы получить положение в пикселях в изображении, вам нужно просто умножить их на фактические размеры в пикселях изображения, но нормализованные координаты позволяют учитывать точку зрения исходного респондента о разрешении неоднозначности в каждом конкретном случае.

person fastcall    schedule 06.08.2008
comment
Привет, было бы здорово увидеть образец кода, который вы собрали, если он еще у вас под рукой. - person Kevin Wilson; 30.07.2009