2011-02-03 7 views
5

me encontré con este ejemplo de pellizcar para acercar a http://forums.create.msdn.com¿Pinch-to-zoom en imágenes grandes?

Aquí es el XAML:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> 
      <StackPanel> 
       <TextBlock Text="Tap to center" Style="{StaticResource PhoneTextNormalStyle}"/> 
       <TextBlock Text="Tap and hold to reset" Style="{StaticResource PhoneTextNormalStyle}"/> 
       <TextBlock Text="Touch and move to drag" Style="{StaticResource PhoneTextNormalStyle}"/> 
       <TextBlock Text="Pinch (touch with two fingers) to scale and rotate" Style="{StaticResource PhoneTextNormalStyle}" TextWrapping="Wrap"/> 
       <TextBlock Text="Flick (drag and release the touch while still moving) will show flick data on bottom of screen." Style="{StaticResource PhoneTextNormalStyle}" TextWrapping="Wrap"/> 
      </StackPanel> 
      <TextBlock x:Name="flickData" Text="Flick:" Style="{StaticResource PhoneTextNormalStyle}" VerticalAlignment="Bottom"/> 
      <Image x:Name="image" Source="/map.jpg" RenderTransformOrigin="0.5,0.5" CacheMode="BitmapCache"> 
       <Image.RenderTransform> 
        <CompositeTransform x:Name="transform"/> 
       </Image.RenderTransform> 
       <toolkit:GestureService.GestureListener> 
        <toolkit:GestureListener 
         Tap="OnTap" Hold="OnHold" 
         DragStarted="OnDragStarted" DragDelta="OnDragDelta" DragCompleted="OnDragCompleted" 
         Flick="OnFlick" 
         PinchStarted="OnPinchStarted" PinchDelta="OnPinchDelta" PinchCompleted="OnPinchCompleted"/> 
       </toolkit:GestureService.GestureListener> 
      </Image> 
     </Grid> 

Y la fuente cs:

public partial class GestureSample : PhoneApplicationPage 
    { 
     double initialAngle; 
     double initialScale; 

     public GestureSample() 
     { 
      InitializeComponent(); 
     } 

     private void OnTap(object sender, GestureEventArgs e) 
     { 
      transform.TranslateX = transform.TranslateY = 0; 
     } 

     private void OnDoubleTap(object sender, GestureEventArgs e) 
     { 
      transform.ScaleX = transform.ScaleY = 1; 
     } 

     private void OnHold(object sender, GestureEventArgs e) 
     { 
      transform.TranslateX = transform.TranslateY = 0; 
      transform.ScaleX = transform.ScaleY = 1; 
      transform.Rotation = 0; 
     } 

     private void OnDragStarted(object sender, DragStartedGestureEventArgs e) 
     { 
      image.Opacity = 0.3; 
     } 

     private void OnDragDelta(object sender, DragDeltaGestureEventArgs e) 
     { 
      transform.TranslateX += e.HorizontalChange; 
      transform.TranslateY += e.VerticalChange; 
     } 

     private void OnDragCompleted(object sender, DragCompletedGestureEventArgs e) 
     { 
      image.Opacity = 1.0; 
     } 

     private void OnPinchStarted(object sender, PinchStartedGestureEventArgs e) 
     { 
      Point point0 = e.GetPosition(image, 0); 
      Point point1 = e.GetPosition(image, 1); 
      Point midpoint = new Point((point0.X + point1.X)/2, (point0.Y + point1.Y)/2); 
      image.RenderTransformOrigin = new Point(midpoint.X/image.ActualWidth, midpoint.Y/image.ActualHeight); 
      initialAngle = transform.Rotation; 
      initialScale = transform.ScaleX; 
      image.Opacity = 0.8; 
     } 

     private void OnPinchDelta(object sender, PinchGestureEventArgs e) 
     { 
      transform.Rotation = initialAngle + e.TotalAngleDelta; 
      transform.ScaleX = transform.ScaleY = initialScale * e.DistanceRatio; 
     } 

     private void OnPinchCompleted(object sender, PinchGestureEventArgs e) 
     { 
      image.Opacity = 1.0; 
     } 

     private void OnFlick(object sender, FlickGestureEventArgs e) 
     { 
      flickData.Text = string.Format("{0} Flick: Angle {1} Velocity {2},{3}", 
       e.Direction, Math.Round(e.Angle), e.HorizontalVelocity, e.VerticalVelocity); 
     } 
    } 

Funciona bastante bien para las pequeñas imágenes (menos luego 2000x2000 píxeles). Pero en mi ejemplo, tengo este enorme mapa de metro (http://www.vasttrafik.se/upload/Linjekartor_hogupplost/Goteborg2010/Linjen%C3%A4tskarta-101212.png o vector http://www.vasttrafik.se/upload/Linjekartor_hogupplost/Goteborg2010/Linjen%C3%A4tskarta-101212.pdf). Sería aún mejor si el usuario pudiera escalar una imagen vectorial, pero incluso la importación de un vector tan grande es un problema serio de rendimiento.

tal vez podría dividir la imagen en varias imágenes "multi-escala" y utilizar este http://dotnetbyexample.blogspot.com/2010/08/windows-phone-7-multi-touch-panzoom.html, pero no se sabe muy bien cómo utilizar su clase :(

¿Alguna idea? ¿Cómo ustedes resolver este problema?

Gracias

Richard

Respuesta

6

El enfoque ideal para su solución es utilizar MultiScaleImage, que está específicamente diseñado para mostrar datos de imágenes de gran tamaño. Sin embargo, para trabajar con MultiScaleImage, necesita obtener sus datos de iamge preparados en el formato correcto. Básicamente, necesita que la imagen se recorta y se vuelve a escalar, etc. para que el usuario cargue la menor cantidad de información posible mientras se acerca y aleja la imagen.

El DeepZoom documentation describe el proceso y tiene enlaces a la herramienta DeepZoom Composer, que utiliza para preparar sus datos de imagen.

Una vez que tenga funcionando el enfoque MultiScaleImage, puede utilizar el comportamiento multitáctil de Laurent (si es necesario) para proporcionar interacciones adicionales del usuario.

+0

Gracias por su respuesta. ¡Sin éxito! Logré ver la imagen de escala múltiple en mi teléfono, pero lleva tiempo cargarla y la interacción no funcionará. Éstos son los archivos dpi: http://www50.zippyshare.com/v/82097441/file.html Y mi xaml: Richard

1

Existe un límite de tamaño en los UIElements de Silverlight en el teléfono. Como ha descubierto, esto es 2000x2000 píxeles. Ningún control individual puede ser más grande que este, de ahí su problema.

Si debe usar una imagen más grande que esta, mire MultiScaleImage.

También tenga en cuenta la posibilidad de problemas de memoria si está utilizando archivos de imagen muy grandes.

Cuestiones relacionadas