Пинч-масштаб для огромных изображений? - PullRequest
5 голосов
/ 03 февраля 2011

Я нашел этот пример Pinch-to-zoom в 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 голосов
/ 03 февраля 2011

Идеальным подходом для вашего решения является использование MultiScaleImage, которое специально разработано для отображения больших данных изображения. Однако для работы с MultiScaleImage вам необходимо подготовить данные iamge в правильном формате. Как правило, вам нужно разрезать и изменить масштаб изображения и т. Д., Чтобы пользователь загружал как можно меньше информации, когда он увеличивал и уменьшал масштаб вашего изображения.

Документация DeepZoom описывает процесс и содержит ссылки на инструмент DeepZoom Composer, который используется для подготовки данных изображения.

Как только вы приступите к работе с подходом MultiScaleImage, вы можете посмотреть, как использовать мультитач-поведение Лорана (при необходимости), чтобы обеспечить дополнительные взаимодействия с пользователем.

1 голос
/ 03 февраля 2011

Существует ограничение размера для элементов Silverlight UIElements на телефоне. Как вы обнаружили, это 2000x2000 пикселей. Ни один элемент управления не может быть больше этого, поэтому ваша проблема.

Если вам нужно использовать изображение большего размера, посмотрите на MultiScaleImage.

Также помните о возможных проблемах с памятью, если вы используете очень большие файлы изображений.

1 голос
/ 03 февраля 2011

Вы слышали о Silverlight Deep-Zoom?

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...