10.2应用实例——移动截图

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

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

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

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 = ;
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属性来进行截取。代码如下所示:

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(, ));
// 创建相对于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元素对象转换为位图。代码如下所示:

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 应用开发》

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

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

欢迎关注我的微博@WP林政   微信公众号:wp开发(号:wpkaifa)

WP8.1技术交流群:372552293

最新文章

  1. 编写高质量代码:改善Java程序的151个建议(第6章:枚举和注解___建议88~92)
  2. ASP.NET MVC5 网站开发实践 - 概述
  3. LINUX内核参数网络相关
  4. JQuery 在循环中设置事件,最后一个覆盖了前面所有的设置
  5. SQLSERVER 数值 四舍五入取整 向上取整 向下取整
  6. 安卓Notification的setLatestEventInfo is undefined出错不存在的解决
  7. GB2312、GBK和UTF-8三种编码以及QT中文显示乱码问题
  8. Rational Rose 2007 破解版安装过程
  9. 从C#到Objective-C
  10. 在 Visual Studio 2013 中创建 ASP.NET Web 项目(1):概述 - 创建 Web 应用程序项目
  11. CC2540开发板学习笔记(九)—— BLE协议简介
  12. 想知道吗?CTO 比普通程序员强在哪?
  13. HDU-3473Minimum Sum
  14. 老李分享:为何要使用 Web Services
  15. 微信支付之01------获取订单微信支付二维码的接口------Java实现
  16. (二叉树 BFS) leetcode993. Cousins in Binary Tree
  17. Python排序算法——冒泡排序
  18. XML学习入门
  19. document.createDocumentFragment()运行效率
  20. Java 基础 - 集合

热门文章

  1. Android源码-学习随笔
  2. poj 3468:A Simple Problem with Integers(线段树,区间修改求和)
  3. poj 1007:DNA Sorting(水题,字符串逆序数排序)
  4. 攻城狮在路上(壹) Hibernate(十八)--- 管理Hibernate的缓存
  5. Angular JS [Draft]
  6. bbed的使用--查看数据文件信息 &amp; sid信息
  7. 【荐】Spring事务配置的五种方式
  8. Json转换利器Gson之实例一-简单对象转化和带泛型的List转化 (转)
  9. javascript 时间倒计时
  10. 让Web API支持$format参数的方法