2012-05-06 14 views
7

Necesito la posición precisa del puntero de mi mouse sobre un PictureBox.Cómo recuperar el factor de zoom de un WinForms PictureBox?

Utilizo el evento MouseMove del PictureBox.

En esta PictureBox, utilizo la propiedad "ampliar" para mostrar una imagen.

¿Cuál es la forma correcta de obtener la posición del mouse en la imagen original (sin zoom)?

¿Hay alguna manera de encontrar el factor de escala y usarlo?

Creo que es necesario utilizar imageOriginalSize/imageShowedSize para recuperar este factor de escala.

puedo utilizar esta función:

float scaleFactorX = mypic.ClientSize.Width/mypic.Image.Size.Width; 
float scaleFactorY = mypic.ClientSize.Height/mypic.Image.Size.Height; 

es posible utilizar este valor para obtener la posición correcta del cursor sobre la imagen?

+0

Supongo que puedes probar: Point cursorPosition = mypic.PointToClient (Cursor.Position); Point positionOverImage = new Point (cursorPosition.X/scaleFactorX, cursorPosition.Y/scaleFactorY) ;. Sin embargo, supongo que puede haber algunos problemas de precisión cuando contabilizas el factor de acercamiento usando este método. Te sugiero que escales la imagen por tu cuenta. –

+0

gracias, pero no funciona. La posición es incorrecta, obtengo el mismo valor cuando uso la posición pointtoclient y eventmouseargs. – devilkkw

+0

Publique el fragmento de código calculando las coordenadas que está utilizando actualmente. –

Respuesta

6

Hoy tuve que resolver el mismo problema. Quería que funcionara para imágenes de cualquier ancho: relación de altura.

Aquí está mi método para encontrar el punto 'unscaled_p' en la imagen original de tamaño completo.

  Point p = pictureBox1.PointToClient(Cursor.Position); 
      Point unscaled_p = new Point(); 

      // image and container dimensions 
      int w_i = pictureBox1.Image.Width; 
      int h_i = pictureBox1.Image.Height; 
      int w_c = pictureBox1.Width; 
      int h_c = pictureBox1.Height; 

El primer truco es determinar si la imagen es una forma horizontal o vertical más grande con relación al recipiente, por lo que sabrá qué dimensión de la imagen se llena el recipiente por completo.

  float imageRatio = w_i/(float)h_i; // image W:H ratio 
      float containerRatio = w_c/(float)h_c; // container W:H ratio 

      if (imageRatio >= containerRatio) 
      { 
       // horizontal image 
       float scaleFactor = w_c/(float)w_i; 
       float scaledHeight = h_i * scaleFactor; 
       // calculate gap between top of container and top of image 
       float filler = Math.Abs(h_c - scaledHeight)/2; 
       unscaled_p.X = (int)(p.X/scaleFactor); 
       unscaled_p.Y = (int)((p.Y - filler)/scaleFactor); 
      } 
      else 
      { 
       // vertical image 
       float scaleFactor = h_c/(float)h_i; 
       float scaledWidth = w_i * scaleFactor; 
       float filler = Math.Abs(w_c - scaledWidth)/2; 
       unscaled_p.X = (int)((p.X - filler)/scaleFactor); 
       unscaled_p.Y = (int)(p.Y/scaleFactor); 
      } 

      return unscaled_p; 

Tenga en cuenta que debido a los centros de zoom de la imagen, la longitud 'relleno' tiene que tenerse en cuenta para determinar la dimensión que no está ocupado por la imagen. El resultado, 'unscaled_p', es el punto en la imagen sin escala que 'p' se correlaciona.

Espero que ayude!

+1

Perfeccione con un pequeño error: para la proporción, no debe usar el ancho y la altura del control completo, pero sí el ancho y alto del Control.ClientSize, sin bordes. Muy a menudo la diferencia no se nota, hasta que se muestra un borde y se hacen algunos cálculos. Verás que faltan algunos píxeles –

1

Si le he entendido bien yo creo que le gustaría hacer algo de esta naturaleza:

Supuesto: el cuadro de imagen se ajusta a la imagen de anchura/altura, no hay espacio entre el borde del cuadro de imagen y la imagen real

ratioX = e.X/pictureBox.ClientSize.Width; 
ratioY = e.Y/pictureBox.ClientSize.Height; 

imageX = image.Width * ratioX; 
imageY = image.Height * ratioY; 

esto debería darle los puntos del píxel en la imagen original.

+0

doesnt't works.its dame el valor 0 cada vez. – devilkkw

+0

Me perdí el '(flotación)' de la relación, haz eso, por el momento si dices que 'var ratioX', entonces probablemente será un' int', lo que significa 'ratioX/Y' siempre será cero. –

Cuestiones relacionadas