[深入浅出WP8.1(Runtime)]生成图片和存储生成的图片文件
7.2.3 使用RenderTargetBitmap类生成图片
RenderTargetBitmap类可以将可视化对象转换为位图,也就是说它可以将任意的UIElement以位图的形式呈现。那么我们在实际的编程中通常会利用RenderTargetBitmap类来对UI界面进行截图操作,比如把程序的界面或者某个控件的外观生成一张图片。
使用RenderTargetBitmap类生成图片一般有两种用途,一种是直接把生成的图片在当前的页面上进行展示,还有一种用途是把生成的图片当作文件存储起来,或者通过某种分享方式把图片文件分享出去。那么第二种用途的编程实现肯定是在第一种的编程实现的基础上来实现的,所以我们首先看一下第一种情况的实现,如何把截图在当前的界面上展示。
使用RenderTargetBitmap类生成图片的操作主要是依赖于RenderTargetBitmap类的RenderAsync方法。RenderAsync方法有两个重载:RenderAsync(UIElement) 和 RenderAsync(UIElement, Int32, Int32),可在后者处指定要与源可视化树的自然大小不同的所需图像源尺寸,没有设置则是按照元素的原始大小生成图片。RenderAsync方法被设计为异步方法,因此无法保证与UI源进行精确的框架同步,但大多数情况下都足够及时。由于 RenderTargetBitmap是ImageSource的子类,因此,可以将其用作Image元素或 ImageBrush画笔的图像源。
下面给出生成程序截图的示例:通过点击屏幕来生成当前程序界面的截图,并把截图用Image控件展示出来,每次的点击都产生一个最新的截图并进行展示。
代码清单7-9:生成程序截图(源代码:第7章\Examples_7_9)
MainPage.xaml文件主要代码
------------------------------------------------------------------------------------------------------------------
<!--注册PointerReleased 事件用于捕获屏幕的单击操作,并在时间处理程序中生成图片-->
<Grid x:Name="root" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
PointerReleased="Grid_PointerReleased">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,35,0,28">
<TextBlock Text="我的应用程序" FontSize="20" />
<TextBlock Text="点击截屏" FontSize="60" />
</StackPanel>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" >
<!--该图片控件用于展示截图图片效果-->
<Image x:Name="img" />
</Grid>
</Grid>
MainPage.xaml.cs文件主要代码
------------------------------------------------------------------------------------------------------------------
// 指针释放的事件处理程序
private async void Grid_PointerReleased(object sender, PointerRoutedEventArgs e)
{
// 创建一个RenderTargetBitmap对象,对界面中的Grid控件root生成图片
RenderTargetBitmap bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(root);
// 把图片展现出来
img.Source = bitmap;
}
7.2.4 存储生成的图片文件
在上文我们讲解了如何把程序界面截图出来放到Image控件上展示,那么我们接下来将继续介绍如何把截图出来的图片保存到程序存储里面。在我们调用RenderAsync方法的时候会初始化RenderTargetBitmap类的对象,但是RenderTargetBitmap类的对象本身并不能作为图片来进行存储,要生成图片文件需要获取到图片的二进制数据。如果你想要获取 DataTransferManager 操作(例如共享协定交换)的图像,或想要使用 Windows.Graphics.Imaging API 将效果应用到图像上或对图像进行转码,那么就需要用到像素数据。如果你想访问RenderTargetBitmap的Pixels数据,你需要在用RenderAsync这个方法将UIElement定义为 RenderTargetBitmap后,再调用RenderTargetBitmap的GetPixelsAsync方法来获得其Pixels数据。该方法返回的是一个IBuffer类型,里面存储的是二进制的位图数。这个IBuffer可以转换为一个Byte数组,数组里面的数据是以BGRA8格式存储的。
以下代码示例如何从一个RenderTargetBitmap对象中获得以byte数组类型存储的像素数。需要特别注意的是IBuffer实例调用的ToArray方法是一个扩展方法,你需要在你的项目中加入System.Runtime.InteropServices.WindowsRuntime这个命名空间。
var bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(elementToRender);
IBuffer pixelBuffer = await bitmap.GetPixelsAsync();
byte[] pixels = pixelBuffer.ToArray();
那么在获取到了图像的二进制数据之后,如果要把二进制的数据生成图片文件,需要使用到BitmapEncoder类。BitmapEncoder类包含创建、编辑和保存图像的各种方法。创建图片文件首先需要调用BitmapEncoder类CreateAsync方法,来使用文件的流来创建一个BitmapEncoder对象,然后再使用BitmapEncoder类的SetPixelData设置图像有关帧的像素数据。SetPixelData的方法参数如下:
SetPixelData(BitmapPixelFormat pixelFormat, BitmapAlphaMode alphaMode, uint width, uint height, double dpiX, double dpiY, byte[] pixels)
其中,pixelFormat表示像素数据的像素格式;alphaMode表示像素数据的alpha模式;width表示像素数据的宽度(以像素为单位);height表示像素数据的高度(以像素为单位);dpiX表示像素数据的水平分辨率(以每英寸点数为单位);dpiY表示像素数据的垂直分辨率(以每英寸点数为单位);pixels表示像素数据。此方法是同步的,因为直到调用 FlushAsync、GoToNextFrameAsync 或 GoToNextFrameAsync(IIterable(IKeyValuePair)) 才会提交数据。此方法将所有像素数据视为sRGB 颜色空间中的像素数据。
下面给出保存截图文件的示例:先使用RenderTargetBitmap类生成程序界面的截图,然后再将截图的二进制数据生成图片文件存储到程序存储中。
代码清单7-10:保存截图文件(源代码:第7章\Examples_7_10)
MainPage.xaml文件主要代码
------------------------------------------------------------------------------------------------------------------
<Grid x:Name="root" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
……省略若干代码
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<Button x:Name="bt_save" Content="存储生成的图片" Click="bt_save_Click"></Button>
<Button x:Name="bt_show" Content="展示存储的图片" Click="bt_show_Click"></Button>
<ScrollViewer BorderBrush="Red" BorderThickness="2" Height="350">
<Image x:Name="img" />
</ScrollViewer>
</StackPanel>
</Grid>
</Grid>
MainPage.xaml.cs文件主要代码
------------------------------------------------------------------------------------------------------------------
// 按钮事件生成图片并保存到程序的存储里面
private async void bt_save_Click(object sender, RoutedEventArgs e)
{
// 生成RenderTargetBitmap对象
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(root);
// 获取图像的二进制数据
var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
// 创建程序文件存储
IStorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
IStorageFile saveFile = await applicationFolder.CreateFileAsync("snapshot.png", CreationCollisionOption.OpenIfExists);
// 把图片的二进制数据写入文件存储
using (var fileStream = await saveFile.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, fileStream);
encoder.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Ignore,
(uint)renderTargetBitmap.PixelWidth,
(uint)renderTargetBitmap.PixelHeight,
DisplayInformation.GetForCurrentView().LogicalDpi,
DisplayInformation.GetForCurrentView().LogicalDpi,
pixelBuffer.ToArray());
await encoder.FlushAsync();
}
}
// 展示程序存储图片的按钮事件
private void bt_show_Click(object sender, RoutedEventArgs e)
{
// “ms-appdata:///local”表示是程序存储的根目录
BitmapImage bitmapImage = new BitmapImage(new Uri("ms-appdata:///local/snapshot.png", UriKind.Absolute));
img.Source = bitmapImage;
}
本文来源于《深入浅出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
[深入浅出WP8.1(Runtime)]生成图片和存储生成的图片文件的更多相关文章
- 如何在mysql中存储音乐和图片文件
如何在mysql中存储音乐和图片文件? 果你想把二进制的数据,比如说图片文件和HTML文件,直接保存在你的MySQL数据库,那么这篇文章就是为你而写的! 我将告诉你怎样通过HTML表单来储存这些文件, ...
- [深入浅出WP8.1(Runtime)]Windows Phone 8.1和Silverlight 8.1的区别
1.2.2 Windows Phone 8.1应用程序模型 Windows Phone 8.1支持多种开发语言来开发应用程序,包括C#.VB.JavaScript和C++,那么本书的代码主要是采用C# ...
- [深入浅出WP8.1(Runtime)]网络编程之HttpClient类
12.2 网络编程之HttpClient类 除了可以使用HttpWebRequest类来实现HTTP网络请求之外,我们还可以使用HttpClient类来实现.对于基本的请求操作,HttpClient类 ...
- [深入浅出WP8.1(Runtime)]应用文件的URI方案
6.2.4 应用文件的URI方案 在上文我们获取文件的方式都是通过应用程序的三个跟目录的文件夹对象来获取文件夹对象和文件对象,那么我们这一小节来讲解一种新的获取文件对象的方式,这种方式就是通过Uri地 ...
- [深入浅出WP8.1(Runtime)]文本块(TextBlock)
4.3 文本块(TextBlock) 文本块(TextBlock)控件是用于显示少量文本的轻量控件,可以通过TextBlock呈现只读的文本,你可以把TextBlock控件理解为一种纯文本的展示控件. ...
- [深入浅出WP8.1(Runtime)]Socket编程之UDP协议
13.3 Socket编程之UDP协议 UDP协议和TCP协议都是Socket编程的协议,但是与TCP协议不同,UDP协议并不提供超时重传,出错重传等功能,也就是说其是不可靠的协议.UDP适用于一次只 ...
- [深入浅出WP8.1(Runtime)]数据绑定的基础
11.1 数据绑定的基础 数据绑定是一种XAML界面和后台数据通信的方式,因为界面和后台数据的通信的场景有多种,并且数据于数据之间也存在着不一样的关联关系,所以数据绑定的实现技巧和方式也是多种多样的. ...
- [深入浅出WP8.1(Runtime)]应用实例——移动截图
10.2应用实例——移动截图 移动截图例子是实现一个把一张图片的某个部分截取出来的功能,并且用户可以选定截取的图片区间.那个该例子会使用ManipulationDelta事件来实现对截取区间的选择.然 ...
- [深入浅出WP8.1(Runtime)]Toast通知
9.1 Toast通知 Toast通知是在屏幕最顶上弹出来的临时通知,是Windows Phone通用的弹出式短暂的通知,默认的系统消息都是采用Toast通知的形式,比如当你手机收到短信的时候,在手机 ...
随机推荐
- oracle数据库出现“批处理中出现错误: ORA-00001: 违反唯一约束条件”解决方法
最近使用oraclede impdp工具全库导入数据库时,在数据库里面使用出现如下情况. SQL state : 违反唯一约束条件 (GDXAORCL.SYS_C0055359) ; nested e ...
- 【转】JQuery插件ajaxFileUpload 异步上传文件(PHP版)
前几天想在手机端做个异步上传图片的功能,平时用的比较多的JQuery图片上传插件是Uploadify这个插件,效果很不错,但是由于手机不支持flash,所以不得不再找一个文件上传插件来用了.后来发现a ...
- Ubuntu中给eclipse和android studio添加桌面快捷图标
Ubuntu 12.04 创建应用程序启动项(可在Unity LaucherPad显示) http://www.cnblogs.com/bluestorm/archive/2012/10/12/272 ...
- Oracle 备份与恢复介绍
一.Oracle备份方式分类:Oracle有两类备份方式:(1)物理备份:是将实际组成数据库的操作系统文件从一处拷贝到另一处的备份过程,通常是从磁盘到磁带.物理备份又分为冷备份.热备份: (2)逻 ...
- 三、spinner
今天 ,看的和学的都不多,就弄了一个spinner控件而已,下面就记录一下spinner 用法吧 基本上说,使用spinner 有三个步骤 一.在布局文件里面设置spinner 控件,这个不用再多说了 ...
- Ubuntu14.04LTS系统输入法的安装
由于安装的时候选择的是英文版,所以一进入系统问题就来了:无法输入中文. 我记得自己直接选的输入法是pinyin那个 在网上看到别人到blog,直接转过来吧,只为自己收藏下,如有需要请联系原作者. 转载 ...
- TCP通讯程序设计
TCP通讯程序设计 这里主要包含客户机和服务器的编程. 一.编程模型函数化 使用函数说明:socket的理解 服务器: 创建socket使用函数----->socket 绑定地址使用函数---- ...
- Java学习笔记(三)——运算符
一.运算符: 1.分类: 2.java中的运算符 (1)其中,++在左,表示先加了再用,++在右,表示先用了再加. (2)% 用来求余数,也称为"取模运算符" 3.赋值运算符 4. ...
- 已解决:Strict Standards: Non-static method cls_image::gd_version() should not be called statically in...
在安装Ecshop的时候,遇到两个⚠️问题: Strict Standards: Non-static method cls_image::gd_version() should not be cal ...
- CF735D Taxes 哥德巴赫猜想\判定素数 \进一步猜想
http://codeforces.com/problemset/problem/735/D 题意是..一个数n的贡献是它的最大的因子,这个因子不能等于它本身 然后呢..现在我们可以将n拆成任意个数的 ...