巨型图片如何使用捏合缩放?

5
I found this Pinch-to-zoom example at http://forums.create.msdn.com 这是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> 

而且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); 
        } 
    }

它对于小图像(小于2000x2000像素)效果很好。但在我的示例中,我有这张巨大的地铁地图(http://www.vasttrafik.se/upload/Linjekartor_hogupplost/Goteborg2010/Linjen%C3%A4tskarta-101212.png或向量http://www.vasttrafik.se/upload/Linjekartor_hogupplost/Goteborg2010/Linjen%C3%A4tskarta-101212.pdf)。如果用户能够缩放矢量图像将更加美观,但是导入如此巨大的矢量图形会引起严重的性能问题。
也许我可以将图像分成几个“多尺度图像”,并使用此http://dotnetbyexample.blogspot.com/2010/08/windows-phone-7-multi-touch-panzoom.html,但我真的不知道如何使用他的类:(
有什么想法吗?你们怎么解决这个问题?
谢谢
理查德
3个回答

6
你的解决方案最理想的方法是使用MultiScaleImage,该方法专门设计用于显示大型图像数据。但是,为了使用MultiScaleImage,您需要准备正确格式的图像数据。基本上,您需要将图像切片并重新缩放等,以便用户在缩放图像时加载尽可能少的信息。

DeepZoom文档描述了该过程,并提供了DeepZoom Composer工具的链接,您可以使用该工具准备图像数据。

一旦您使用MultiScaleImage方法成功,您可以考虑使用劳伦特的多点触控行为(如果必要)来提供额外的用户交互。


谢谢您的回复。但是没有成功!我已经设法在手机上查看多尺度图像,但加载需要很长时间,而且交互不起作用。以下是dpi文件: http://www50.zippyshare.com/v/82097441/file.html以及我的xaml代码: <MultiScaleImage x:Name="msi" Source="/Vasttrafik;component/LineMapDZI/dzc_output.xml"> <i:Interaction.Behaviors> LJBehaviours:PanZoomBehaviour/ </i:Interaction.Behaviors> </MultiScaleImage> - Richard

1

1

电话中的 Silverlight UIElement 有大小限制。正如您所发现的那样,它是 2000x2000 像素。没有任何一个控件可以比此更大 - 因此出现了您的问题。

如果您必须使用大于此尺寸的图像,请查看 MultiScaleImage

此外,请注意,如果您使用非常大的图像文件,则可能会出现内存问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接