首页 > 代码库 > WindowsPhone8可缩放图片控件的实现

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

WindowsPhone8可缩放图片控件的实现