[深刻浅出WP8.1(Runtime)]应用实例——移动截图

10.2应用实例——移动截图

    移动截图例子是实现一个把一张图片的某个部分截取出来的功能,而且用户能够选定截取的图片区间。那个该例子会使用ManipulationDelta事件来实现对截取区间的选择。而后使用UIElement元素的Clip属性对图片进行局部截取。html

    下面给出移动截图的示例:该示例主要有3个主要的逻辑分别是截图区域的选择、图片的局部截取和截图的展现。微信

    代码清单10-3移动截图(源代码:第10章\Examples_10_3)async

MainPage.xaml文件主要代码:在UI上image1是图片的展现,image2是显示截取以后的图片,命名为LayoutRoot的Grid控件则是图片和截图区域的容器。
------------------------------------------------------------------------------------------------------------------
    <ScrollViewer>
        <StackPanel>        
            <Grid x:Name="LayoutRoot">
                <Image Source="/test.jpg"  Height="460" Width="300"  Name="image1"/>
            </Grid>
            <Button Content="剪切" x:Name="button"></Button>
            <Image  Name="image2" />
        </StackPanel>
    </ScrollViewer>

10.2.1 截图区域的选择

    截图区域的选择是指要动画手指滑动的方式来控制截图的位置和大小,那么在该例子里面实现的逻辑是以照片的中心为截图区域的中心,而后用户能够经过滑动来改变这个截图矩形的宽度和高度。那么咱们实现的思路是,先要在图片上面添加一个矩形控件Rectangle,而后给这个Rectangle控件添加上ManipulationDelta事件,监控用户在截图矩形上面的滑动状况,在ManipulationDelta事件的处理程序上调整Rectangle控件的大小。代码以下所示:动画

MainPage.xaml.cs文件部分代码:截图区域的选择。
------------------------------------------------------------------------------------------------------------------
    public MainPage()
    {
        this.InitializeComponent();
        button.Click += button_Click;
        // 设置图片上方的截图区域
        SetPicture();
    }
    // 添加图片的截图区域
    void SetPicture()
    {
        // 建立一个Rectangle控件
        Rectangle rect = new Rectangle();
        rect.Opacity = 0.5;
        rect.Fill = new SolidColorBrush(Colors.White);
        rect.Height = image1.Height;
        rect.Width = image1.Width;
        rect.Stroke = new SolidColorBrush(Colors.Red);
        rect.StrokeThickness = 2;
        rect.Margin = image1.Margin;
        // 添加触摸滑动过程的事件监控
        rect.ManipulationMode = ManipulationModes.All;
        rect.ManipulationDelta += rect_ManipulationDelta;
        // 把Rectangle控件添加到LayoutRoot上,这时候该控件会出如今图片的上方
        LayoutRoot.Children.Add(rect);
        LayoutRoot.Height = image1.Height;
        LayoutRoot.Width = image1.Width;
    }
    // 利用手指滑动来改变截图框的位置和大小
    void rect_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
    {
        // 获取事件的发送方,也就是截图区域Rectangle控件
        Rectangle croppingRectangle = (Rectangle)sender;
        // 经过手指的位移来更改Rectangle控件的宽度和高度
        // 往右滑动宽度减小(X为正),往左滑动宽度增长(X为负)
        if (croppingRectangle.Width >= (int)e.Delta.Translation.X)
            croppingRectangle.Width -= (int)e.Delta.Translation.X;
        // 往下滑动高度减小(X为正),往上滑动高度增长(X为负)
        if (croppingRectangle.Height >= (int)e.Delta.Translation.Y)
            croppingRectangle.Height -= (int)e.Delta.Translation.Y;
    }

10.2.2 图片的局部截取

    在截图区域已经定位好以后,接下来的这一步就是须要根据截图区域的位置来把图片截取出来,那么在这一步里面最主要的逻辑是把Rectangle控件的位置大小信息转化为image1图片里面的相对位置的区域信息,而后再经过Clip属性来进行截取。代码以下所示:this

MainPage.xaml.cs文件部分代码:图片的局部截取。
------------------------------------------------------------------------------------------------------------------
    // 截取图片的区域
    void ClipImage()
    {
        // 建立一个矩形的几何图形,用于赋值给Clip属性,注意:作为属性使用的几何图形必须是*Geometry类型的图形
        RectangleGeometry geo = new RectangleGeometry();
        // 获取截图的矩形控件,经过Grid容器向下查找
        Rectangle r = (Rectangle)(from c in LayoutRoot.Children where c.Opacity == 0.5 select c).First();
        // 把截图的矩形控件的位置信息转换成为相对于Grid容器的位置信息
        GeneralTransform gt = r.TransformToVisual(LayoutRoot);
        // 获取截图区域左上角的坐标,意思是原来r的左上角坐标(0, 0)在LayoutRoot上的坐标的转换
        Point p = gt.TransformPoint(new Point(0, 0));
        // 建立相对于LayoutRoot上的截图区域
        geo.Rect = new Rect(p.X, p.Y, r.Width, r.Height);
        image1.Clip = geo;
        // 把截图控件隐藏起来
        r.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
    }

10.2.3 截图的展现

    截图展现是指把最终截取的图片展现出来,经过Clip属性把图片截取出来以后,实际上并非把图片给剪切了,它仅仅只是把其余区域的部分给挡住了而已,那么要把真是的截图区域获取出来,可使用RenderTargetBitmap类来实现。RenderTargetBitmap类能够把将 UI元素对象转换为位图。代码以下所示:spa

MainPage.xaml.cs文件部分代码:截图的展现。
------------------------------------------------------------------------------------------------------------------
    //剪切按钮事件
    async void button_Click(object sender, RoutedEventArgs e)
    {
        // 调用ClipImage方法,实现图片的局部截取
        ClipImage();
        // 建立一个RenderTargetBitmap对象,并调用RenderAsync方法把UI元素LayoutRoot转化成为RenderTargetBitmap对象
        var bitmap = new RenderTargetBitmap();
        await bitmap.RenderAsync(LayoutRoot);
        // 因为RenderTargetBitmap类原本就是从ImageSource类派生的,因此能够直接复制给图片控件进行显示
        image2.Source = bitmap;
    }

本文来源于《深刻浅出Windows Phone 8.1 应用开发》code

WP8.1 Runtime文章列表:http://www.cnblogs.com/linzheng/p/3998037.htmlorm

源代码下载:http://vdisk.weibo.com/s/zt_pyrfNHb99Ohtm

欢迎关注个人微博@WP林政   微信公众号:wp开发(号:wpkaifa)对象

WP8.1技术交流群:372552293