开发者

Pinch-to-zoom on huge images?

开发者 https://www.devze.com 2023-02-08 02:29 出处:网络
I found this Pinch-to-zoom example at http://forums.create.msdn.com Here is the xaml: <Grid x:Name=\"ContentPanel\" Grid.Row=\"1\" Margin=\"12,0,12,0\">

I found this Pinch-to-zoom example at http://forums.create.msdn.com

Here is the xaml:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> 
            <StackPanel> 
                <Text开发者_如何学CBlock 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> 

And the cs source:

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

It works pretty well for small images (less then 2000x2000 pixels). But in my example, i have this huge metro map (http://www.vasttrafik.se/upload/Linjekartor_hogupplost/Goteborg2010/Linjen%C3%A4tskarta-101212.png or vector http://www.vasttrafik.se/upload/Linjekartor_hogupplost/Goteborg2010/Linjen%C3%A4tskarta-101212.pdf). It would be even nicer if the user could scale a vector image but even importing such a huge vector is a serious performance issue.

Maybe i could split the image up into several "multi-scale images" and use this http://dotnetbyexample.blogspot.com/2010/08/windows-phone-7-multi-touch-panzoom.html, but i don't really know how to use his class :(

Any ideas? How would you guys solve this problem?

Thanks

Richard


The ideal approach for your solution is to use MultiScaleImage, which is specifically designed to display large image data. However, in order to work with MultiScaleImage you need to get your iamge data prepared int he right format. Basically, you need the image sliced up and rescaled, etc so that the user loads as little information as possible while they zoom in and out of your image.

The DeepZoom documentation describes the process and has links to the DeepZoom Composer tool, which you use to prepare your image data.

Once you've got the MultiScaleImage approach working, you can then look at using Laurent's Multitouch Behavior (if necessary) to provide additional user interactions.


Have you heard of Silverlight Deep-Zoom?

http://msdn.microsoft.com/en-us/library/cc645050(v=vs.95).aspx


There is a size limit on Silverlight UIElements on the phone. As you have discovered, this is 2000x2000 pixels. No single control can be larger than this—hence your issue.

If you must use an image larger than this look at the MultiScaleImage.

Also be aware of the potential for memory issues if you're using very large image files.

0

精彩评论

暂无评论...
验证码 换一张
取 消