zoukankan      html  css  js  c++  java
  • WindowsPhone8可缩放图片控件的实现

    xaml中添加:

    <ViewportControl x:Name="viewport" DoubleTap="OnDoubleTap"
            ManipulationStarted="OnManipulationStarted" ManipulationDelta="OnManipulationDelta" 
                         ManipulationCompleted="OnManipulationCompleted" ViewportChanged="viewport_ViewportChanged">
        <Canvas x:Name="canvas">
            <Image x:Name="image" 
                        RenderTransformOrigin="0,0" CacheMode="BitmapCache"
                       ImageOpened="OnImageOpened">
                <Image.RenderTransform>
                    <ScaleTransform x:Name="xform"/>
                </Image.RenderTransform>
            </Image>
        </Canvas>
    </ViewportControl>
    

      cs中添加:

    namespace ImageExtend
    {
        public partial class ZoomImage : UserControl
        {
            public static readonly DependencyProperty SourceProperty
                = DependencyProperty.Register("Source", typeof(ImageSource), typeof(ZoomImage), new PropertyMetadata(OnImageSourceChanged));
            private static void OnImageSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                if (d != null && d is ZoomImage)
                {
                    (d as ZoomImage).SetImage((ImageSource)e.NewValue);
                }
            }
            public ImageSource Source
            {
                get
                {
                    return (ImageSource)GetValue(SourceProperty);
                }
                set
                {
                    SetValue(SourceProperty, value);
                }
            }
     
            const double MaxScale = 10;
     
            double _scale = 1.0;
            double _minScale;
            double _coercedScale;
            double _originalScale;
     
            Size _viewportSize;
            bool _pinching;
            Point _screenMidpoint;
            Point _relativeMidpoint;
     
            BitmapImage _bitmap;
     
     
            public ZoomImage()
            {
                InitializeComponent();
                this.Loaded += ZoomImage_Loaded;
            }
     
            void ZoomImage_Loaded(object sender, RoutedEventArgs e)
            {
                if (Source != null)
                {
                    SetImage(Source);
                }
            }
     
            void SetImage(ImageSource img)
            {
                image.Source = img;
            }
     
            /// <summary> 
            /// Either the user has manipulated the image or the size of the viewport has changed. We only 
            /// care about the size. 
            /// </summary> 
            void viewport_ViewportChanged(object sender, System.Windows.Controls.Primitives.ViewportChangedEventArgs e)
            {
                Size newSize = new Size(viewport.Viewport.Width, viewport.Viewport.Height);
                if (newSize != _viewportSize)
                {
                    _viewportSize = newSize;
                    CoerceScale(true);
                    ResizeImage(false);
                }
            }
     
            /// <summary> 
            /// Handler for the ManipulationStarted event. Set initial state in case 
            /// it becomes a pinch later. 
            /// </summary> 
            void OnManipulationStarted(object sender, ManipulationStartedEventArgs e)
            {
                _pinching = false;
                _originalScale = _scale;
            }
     
            /// <summary> 
            /// Handler for the ManipulationDelta event. It may or may not be a pinch. If it is not a  
            /// pinch, the ViewportControl will take care of it. 
            /// </summary> 
            /// <param name="sender"></param> 
            /// <param name="e"></param> 
            void OnManipulationDelta(object sender, ManipulationDeltaEventArgs e)
            {
                if (e.PinchManipulation != null)
                {
                    e.Handled = true;
     
                    if (!_pinching)
                    {
                        _pinching = true;
                        Point center = e.PinchManipulation.Original.Center;
                        _relativeMidpoint = new Point(center.X / image.ActualWidth, center.Y / image.ActualHeight);
     
                        var xform = image.TransformToVisual(viewport);
                        _screenMidpoint = xform.Transform(center);
                    }
     
                    _scale = _originalScale * e.PinchManipulation.CumulativeScale;
     
                    CoerceScale(false);
                    ResizeImage(false);
                }
                else if (_pinching)
                {
                    _pinching = false;
                    _originalScale = _scale = _coercedScale;
                }
            }
     
            /// <summary> 
            /// The manipulation has completed (no touch points anymore) so reset state. 
            /// </summary> 
            void OnManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
            {
                _pinching = false;
                _scale = _coercedScale;
            }
     
     
            /// <summary> 
            /// When a new image is opened, set its initial scale. 
            /// </summary> 
            void OnImageOpened(object sender, RoutedEventArgs e)
            {
                _bitmap = (BitmapImage)image.Source;
     
                // Set scale to the minimum, and then save it. 
                _scale = 0;
                CoerceScale(true);
                _scale = _coercedScale;
     
                ResizeImage(true);
            }
     
            /// <summary> 
            /// Adjust the size of the image according to the coerced scale factor. Optionally 
            /// center the image, otherwise, try to keep the original midpoint of the pinch 
            /// in the same spot on the screen regardless of the scale. 
            /// </summary> 
            /// <param name="center"></param> 
            void ResizeImage(bool center)
            {
                if (_coercedScale != 0 && _bitmap != null)
                {
                    double newWidth = canvas.Width = Math.Round(_bitmap.PixelWidth * _coercedScale);
                    double newHeight = canvas.Height = Math.Round(_bitmap.PixelHeight * _coercedScale);
     
                    xform.ScaleX = xform.ScaleY = _coercedScale;
     
                    viewport.Bounds = new Rect(0, 0, newWidth, newHeight);
     
                    if (center)
                    {
                        viewport.SetViewportOrigin(
                            new Point(
                                Math.Round((newWidth - viewport.ActualWidth) / 2),
                                Math.Round((newHeight - viewport.ActualHeight) / 2)
                                ));
                    }
                    else
                    {
                        Point newImgMid = new Point(newWidth * _relativeMidpoint.X, newHeight * _relativeMidpoint.Y);
                        Point origin = new Point(newImgMid.X - _screenMidpoint.X, newImgMid.Y - _screenMidpoint.Y);
                        viewport.SetViewportOrigin(origin);
                    }
                }
            }
     
            /// <summary> 
            /// Coerce the scale into being within the proper range. Optionally compute the constraints  
            /// on the scale so that it will always fill the entire screen and will never get too big  
            /// to be contained in a hardware surface. 
            /// </summary> 
            /// <param name="recompute">Will recompute the min max scale if true.</param> 
            void CoerceScale(bool recompute)
            {
                if (recompute && _bitmap != null && viewport != null)
                {
                    // Calculate the minimum scale to fit the viewport 
                    double minX = viewport.ActualWidth / _bitmap.PixelWidth;
                    double minY = viewport.ActualHeight / _bitmap.PixelHeight;
     
                    _minScale = Math.Min(minX, minY);
                }
     
                _coercedScale = Math.Min(MaxScale, Math.Max(_scale, _minScale));
     
            }
     
            private void OnDoubleTap(object sender, GestureEventArgs e)
            {
                e.Handled = true;
     
                _scale = 0;
                CoerceScale(true);
                _scale = _coercedScale;
     
                ResizeImage(true);
            }
        }
    }
    

      详细说明:http://wp.662p.com/thread-8171-1-1.html

  • 相关阅读:
    什么是webview
    juqery.fn.extend和jquery.extend
    LeetCode
    5. Longest Palindromic Substring
    42. Trapping Rain Water
    11. Container With Most Water
    621. Task Scheduler
    49. Group Anagrams
    739. Daily Temperatures
    3. Longest Substring Without Repeating Characters
  • 原文地址:https://www.cnblogs.com/liniuzen/p/3985774.html
Copyright © 2011-2022 走看看