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

时间: 2024-10-25 07:41:00

WindowsPhone8可缩放图片控件的实现的相关文章

wxPython缩放图片控件的一个小例子

前几天写程序的时候,想有个自适应的图片控件,但是一直没有找到合适的解决方案.今天终于解决了这个问题,发在这里,以供参考. 程序截图: 文件下载地址: http://files.cnblogs.com/zzrom/poker.zip wxPython缩放图片控件的一个小例子

Android ImageButton图像完全填充缩放到控件

如果你发现你写程序的时候像我一样,发现图片怎么都无法拉伸填充到ImageButton 里面.而且就算能缩放到控件,但是图像较小,而且总会在 ImageButton周围有一圈边框!当你遇到这一些列问题的这时候你就可以收藏并吸收这个经验了. 总的过程:我先给出关键代码→ 分析给出的两种解决方案→ 我详细介绍一下边框出现的原因个解决办法.→ 最后就是些注意事项了 工具/原料 遇到问题尽可能冷静下来的心情. 记住收藏好我这条经验. ImageButton的长宽最好是固定的.注意事项里面我会告诉你为什么

自定义圆角图片控件(Xfermode方式)

苹果都放弃自己的棱角了... 看惯了方方正正的图片,乍一看到圆角图片觉得挺漂亮的.可当满世界都是圆角图片的时候,我又开始怀念那些棱角了~之前仓促的写过一个,今天拿过来又修改了一下,现在贴在这里,以方便以后ctrl+c.ctrl+v~~~~~ 一.目标 自定义一个图片控件,有圆形和圆角两种选择.控件的行为和ImageView一致! 二.思路 扩展ImageView控件,重写其onDraw方法.一开始还想重写onMeasure方法,如果显示圆形图片强制宽高相等,没能行得通(代码中会说明).圆角图片以

VS2010/MFC常用控件:图片控件Picture Control

图片控件Picture Control 本节主要讲一种简单实用的控件,图片控件Picture Control.我们可以在界面某个位置放入图片控件,显示图片以美化界面. 图片控件简介 图片控件和前面讲到的静态文本框都是静态文本控件,因此两者的使用方法有很多相同之处,所属类都是CStatic类,有关成员函数已在前面介绍,这里就不重复了. 图片控件静态和动态加载图片 鸡啄米下面为大家演示如何为图片控件静态和动态加载位图图片. 1. 图片控件静态加载图片 1)创建一个基于对话框的MFC工程,名称设置为“

MFC 学习之 模态对话框图片控件上作图

首先说明一点,onpaint 是更新面板用的,作图的话应在控件上进行. 新建 MFC 对话框工程,面板上添加按钮 IDC_START , IDC_SHOW , IDC_STOP 添加两个对话框,ID 分别设为(简写)ld 和 cd. ld 上添加三个图片控件,并且每一个均关联一个 CSTATIC 型变量. cd 上添加一个图片控件,操作如上. 分别为两个对话框添加类,名称自己设,我的是 CLineDlg 和 CCompDlg . 主对话框头文件中包含两个类的头文件. 添加声明: CLineDlg

为OLED屏增加GUI支持5:图片控件

本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:WIN10 开发环境:MDK5.13 MCU:STM32F103 说明: 本文定义了图片控件.OLED屏是单色屏,所以本图片控件支持的是单色BMP图像. 将普通图像转换为单色图片可以用工具BmpCvt.exe.将转换后的BMP图像转换为hex文件,可以用Bin2C.exe.这两个工具都是emwin自带工具. 源代码: 转换后的hex文件再整理成如下的示例格式: battery0.c /*

GTK常用控件之图片控件( GtkImage )

图片控件和标签的作用很类似,都是作为显示用的,只是图片控件显示的内容是图片. 图片控件的创建: GtkWidget *gtk_image_new_from_file( const gchar *filename ); filename:图片的名字,带路径的话需要加上路径( 相对或绝对 ) 返回值:图片控件指针 通过上面方法创建的图片控件,以图片默认大小来显示,不能修改其大小.如果要改变图片的大小,我们要借助图片资源对象GdkPixbuf,需要注意的是,GdkPixbuf不属于控件类,它以 Gdk

MFC 对话框Picture Control(图片控件)中静态和动态显示Bmp图片

最近有同学问我如何实现MFC基于对话框在图片控件中加载图片?其实使用MFC显示图片的方法各种各样,但是还是有些同学不知道怎样显示.以前在<数字图像处理>课程中完成的软件都是基于单文档的程序,这里介绍两种在对话框picthre控件中显示BMP图片的最简单基础的方法. ~~方法可能并不完美,高手忽略,但是提供一种能运行的方法,希望对刚接触这方面知识的同学有所帮助.可能你觉得文章过于简单或者有些过于详细叙述(点到即可我并不反对),但也为哪些入门同学想想,当初自己也是一头雾水. 一.静态显示bmp图片

VC++图片控件(Picture Control)显示资源位图(BMP)、文件位图(BMP)、其它格式文件图片(JPG\PNG\BMP)的方法

在VC++ MFC编程中,我们常使用Picture Control图片控件来显示图像.下面简单归纳几种显示不同的方式: (实例可在我的CSDN资源中下载:http://download.csdn.net/detail/margin1988/8341525) 第一种.资源位图方式显示BMP图片 如果要显示的是一张BMP位图,则可以采用资源位图方式,具体步骤如下: (1)将BMP文件拷贝到工程的res目录下: (2)在对话框中添加一个Picture Control控件,例如:ID为IDC_STATI