2011-07-15 23 views
6

Tengo una imagen renderizada grande y necesito una sección ampliada de lo que está debajo del cursor del usuario.¿Cómo construir una lupa en WPF C# 4.0?

Mi imagen está dentro de una cuadrícula y se define en XAML de esta manera:

<Grid x:Name="RootImgGrid" Background="#FF333333" > 
    <Viewbox x:Name="imgViewBox" Margin="1,1,1,1" Stretch="Fill" > 
     <Canvas x:Name="imgCanvas" ClipToBounds="True" Width="{Binding ElementName=RootImgGrid, Path=ActualWidth}" Height="{Binding ElementName=RootImgGrid, Path=ActualHeight}"> 
      <Image x:Name="imgObj" MouseWheel="img_MouseWheel" Cursor="Hand" MouseMove="Img_MouseMove" MouseDown="Img_MouseDown" MouseUp="Img_MouseUp" > 
       <Image.RenderTransform> 
        <TransformGroup x:Name="imgTransformGroup"> 
         <ScaleTransform x:Name="imgScaleTransform"></ScaleTransform> 
         <TranslateTransform x:Name="imgTranslateTransform"></TranslateTransform> 
        </TransformGroup> 
       </Image.RenderTransform> 
       <Image.LayoutTransform> 
        <RotateTransform x:Name="imgRotateTransform"></RotateTransform> 
       </Image.LayoutTransform> 
      </Image> 
     </Canvas> 
    </Viewbox> 
</Grid> 

Y tengo un área ampliada, donde debe aparecer la imagen debajo de mi cursor de zoom de 2x.

<Viewbox x:Name="imgViewBoxMagnifier" Width="400" Height="90"> 
    <Canvas x:Name="imgCanvasMagnifier" Width="400" Height="90"> 
     <Canvas.Clip> 
      <RectangleGeometry Rect="0,0,400,90" /> 
     </Canvas.Clip> 
     <Image x:Name="imgMagnifier" Margin="2" Width="400" Height="90"> 
      <Image.RenderTransform> 
       <TransformGroup x:Name="imgMagnifierTransformGroup"> 
        <ScaleTransform x:Name="imgMagnifierScaleTransform"></ScaleTransform> 
        <TranslateTransform x:Name="imgMagnifierTranslateTransform"></TranslateTransform> 
       </TransformGroup> 
      </Image.RenderTransform> 
      <Image.LayoutTransform> 
       <RotateTransform x:Name="imgMagnifierRotateTransform"></RotateTransform> 
      </Image.LayoutTransform> 
     </Image> 
    </Canvas> 
</Viewbox> 

Ahora, en mi código .CS Tengo la función que debe mostrar la imagen ampliada:

public void Magnifier(Canvas imgCanvas, Image imgObject, Image imgMagnifier, MouseEventArgs e) 
    { 
     Int32 width = 400; 
     Int32 height = 90; 

     if (imgMagnifier.Source != imgObject.Source) 
     { 
      imgMagnifier.Source = imgObject.Source; 
     } 

     Size size = imgObject.RenderSize; 
     RotateTransform rt = (RotateTransform)imgObject.LayoutTransform; 
     TranslateTransform tt = (TranslateTransform)((TransformGroup)imgObject.RenderTransform).Children[1]; 
     ScaleTransform st = (ScaleTransform)((System.Windows.Media.TransformGroup)(imgObject.RenderTransform)).Children[0]; 
     Double x = e.GetPosition(imgCanvas).X - tt.X; 
     Double y = e.GetPosition(imgCanvas).Y - tt.Y; 
     Point pos = e.MouseDevice.GetPosition(imgCanvas); 

     TransformGroup transformGroup = new TransformGroup(); 
     ScaleTransform scale = new ScaleTransform(); 

     scale.CenterX = x; 
     scale.CenterY = y; 
     scale.ScaleX = st.ScaleX * 10; 
     scale.ScaleY = st.ScaleY * 10; 
     transformGroup.Children.Add(scale); 

     TranslateTransform translate = new TranslateTransform(); 
     translate.X = ??????????????????; 
     translate.Y = ??????????????????; 
     transformGroup.Children.Add(translate); 

     imgMagnifier.RenderTransform = transformGroup; 

    } 

¿Cómo puedo encontrar el valor correcto de los "?????? ??

translate.X = -x * 10/(size.Width/400); 
translate.Y = -y * 10/(size.Height/90); 

Muestra la imagen correcta, aumentada, pero no muestra el área de la imagen debajo de mi cursor.

Gracias de antemano.

Respuesta

8

Como no se encontró ninguna solución empaquetada, he desarrollado desde cero un completo y funcional Microsoft VS 2010 Proyecto Lupa zoom C# 4.0 WPF.

Incluye ampliar, alejar, girar, ajustar al ancho y el área ampliada.

Siéntase libre de descargar y hacerlo aún mejor.

WPF Magnifier C# 4.0

Esperamos que disfrute. Vote si lo encuentra útil.

public void Magnifier(Canvas imgCanvas, Image imgObject, Canvas imgCanvasMagnifier, Image imgMagnifier, MouseEventArgs e) 
    { 
     Double width = imgCanvasMagnifier.Width; 
     Double height = imgCanvasMagnifier.Height; 
     Int32 zoom = 3; 

     String txtDebug = String.Empty; 
     String txtZoom = String.Empty; 

     if (imgMagnifier.Source != imgObject.Source) 
     { 
      imgMagnifier.Source = imgObject.Source; 
     } 

     Size size = imgObject.RenderSize; 
     RotateTransform rt = (RotateTransform)imgObject.LayoutTransform; 
     TranslateTransform tt = (TranslateTransform)((TransformGroup)imgObject.RenderTransform).Children[1]; 
     ScaleTransform st = (ScaleTransform)((System.Windows.Media.TransformGroup)(imgObject.RenderTransform)).Children[0]; 
     Double x = e.GetPosition(imgCanvas).X - tt.X; 
     Double y = e.GetPosition(imgCanvas).Y - tt.Y; 
     Point pos = e.MouseDevice.GetPosition(imgCanvas); 
     var wnd = Canvas.GetTop(imgObject); 

     TransformGroup transformGroup = new TransformGroup(); 
     ScaleTransform scale = new ScaleTransform(); 

     scale.ScaleX = st.ScaleX * zoom; 
     scale.ScaleY = st.ScaleY * zoom; 

     RotateTransform rotate = new RotateTransform(); 
     rotate.Angle = rt.Angle; 

     TranslateTransform translate = new TranslateTransform(); 

     Double centerX = st.CenterX * (st.ScaleX - 1); 
     Double centerY = st.CenterY * (st.ScaleY - 1); 

     if (rt.Angle == 0) 
     { 
      translate.X = -(x + centerX)/st.ScaleX; 
      translate.Y = -(y + centerY)/st.ScaleY; 
      scale.CenterX = (x + centerX)/st.ScaleX; 
      scale.CenterY = (y + centerY)/st.ScaleY; 
     } 
     if (rt.Angle == 90) 
     { 
      translate.X = -(x + centerX)/st.ScaleX; 
      translate.Y = -(y + centerY)/st.ScaleY; 
      translate.X += imgObject.ActualHeight * st.ScaleX * zoom; 
      scale.CenterX = (x + centerX)/st.ScaleX; 
      scale.CenterY = (y + centerY)/st.ScaleY; 
     } 

     if (rt.Angle == 180) 
     { 
      translate.X = -(x + centerX)/st.ScaleX; 
      translate.Y = -(y + centerY)/st.ScaleY; 
      translate.X += imgObject.ActualWidth * st.ScaleX * zoom; 
      translate.Y += imgObject.ActualHeight * st.ScaleY * zoom; 
      scale.CenterX = (x + centerX)/st.ScaleX; 
      scale.CenterY = (y + centerY)/st.ScaleY; 
     } 

     if (rt.Angle == 270) 
     { 
      translate.X = -(x + centerX)/st.ScaleX; 
      translate.Y = -(y + centerY)/st.ScaleY; 
      translate.Y += imgObject.ActualWidth * st.ScaleX * zoom; 
      scale.CenterX = (x + centerX)/st.ScaleX; 
      scale.CenterY = (y + centerY)/st.ScaleY; 
     } 

     translate.X += width/2; 
     translate.Y += height/2; 

     transformGroup.Children.Add(rotate); 
     transformGroup.Children.Add(scale); 
     transformGroup.Children.Add(translate); 


     imgMagnifier.RenderTransform = transformGroup; 

    } 
+1

¿Qué tal si revisamos el código en github y será indexado en caso de que las personas lo busquen? – Candide

+0

Claro. Enlace actualizado –

0

FYI: Nunca he hecho nada con WPF y aproveché esta oportunidad para aprender. Aquí está mi solución:

Primero, desactivé el estiramiento en ambas imágenes: Stretch = "None" y eliminé las definiciones de alto y ancho en las imágenes.

A continuación, el código subyacente es:

double xFactor = 2, yFactor = 2; 

    Size size = imgObject.RenderSize; 
    Size magSize = new Size(width: imgMagnifier.RenderSize.Width * xFactor, 
          height: imgMagnifier.RenderSize.Height * yFactor); 

    Point pos = e.MouseDevice.GetPosition(imgCanvas); 

    var transformGroup = new TransformGroup(); 
    var scale = new ScaleTransform(); 
    scale.CenterX = 0; 
    scale.CenterY = 0; 
    scale.ScaleX = xFactor; 
    scale.ScaleY = yFactor; 
    transformGroup.Children.Add(scale); 

    var translate = new TranslateTransform(); 
    translate.X = -pos.X * xFactor + imgCanvasMagnifier.Width/2; 
    translate.Y = -pos.Y * yFactor + imgCanvasMagnifier.Height/2; 
    transformGroup.Children.Add(translate); 

    imgMagnifier.RenderTransform = transformGroup; 
Cuestiones relacionadas