【WP8.1开发】RenderTargetBitmap类的特殊用途
相信,耍过WPF的人都知道RenderTargetBitmap这个玩意儿,这家伙比较有意思,它可以将用户界面上呈现的东西写入到内存的位图对象,从而开发者可以在应用程序中使用它,或者将其保存为图像文件。
在Runtime API里面也有这个位图组件,可以将UI元素呈现到位图中,当然,它也不是万能的,首先,要写入到位图中的UI对象必须已经在用户界面上呈现了,也就是说,只要你能看到界面上出现的东东,它才会写入位图对象;其次,要呈现到位图中的UI元素需要位于可视化树中,我简单地总结为:只要是放在Page内并且可见的元素,都可以生成位图。
调用RenderTargetBitmap类的RenderAsync方法来将可视化对象呈现到RenderTargetBitmap中,如果只是在应用程序中显示该生成的位图,那么,直接把RenderTargetBitmap对象赋值给Image控件的Source属性即可。
要是希望保存为图像文件,就要用到BitmapEncoder类,也就是图像编码。大家知道,在编码图像文件时,是向流中写入字节数组(byte[])作为图像的像素数据的,那么,如何提取RenderTargetBitmap位图中的像素数据呢。你会发现RenderTargetBitmap类有个GetPixelsAsync方法,对的,通过该方法就可以返回位图的像素数据,只不过其类型为IBuffer,这样大家又会疑惑了,如何变成byte[]呢?
勿急,你只要引入System.Runtime.InteropServices.WindowsRuntime命名空间,里面就有相关类型为IBuffer定义了扩展方法——ToArray,调用它可以返回byte[]。
之后的事情就好办了。
理论永远是抽象的,咱们还是干点实事吧,这里我弄了个不那么美观的示例。
示例项目中有四张图片,顺便Show一下老周的书法作品。在应用页面上,把这四张图片分别作为画刷来填充图形。XAML如下:
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition/>
- <RowDefinition Height="Auto"/>
- </Grid.RowDefinitions>
- <Canvas x:Name="cv">
- <Ellipse Width="250" Height="200" Canvas.Left="50" Canvas.Top="20">
- <Ellipse.Fill>
- <ImageBrush ImageSource="/01.png" Stretch="UniformToFill"/>
- </Ellipse.Fill>
- </Ellipse>
- <Rectangle Width="180" Height="250" Canvas.Top="240" Canvas.Left="10" RadiusX="12" RadiusY="20">
- <Rectangle.Fill>
- <ImageBrush ImageSource="/02.png" Stretch="UniformToFill"/>
- </Rectangle.Fill>
- </Rectangle>
- <Polygon Points="50,0 100,50 50,100 0,50" Width="240" Height="240" Canvas.Left="150" Canvas.Top="230" Stretch="Uniform">
- <Polygon.Fill>
- <ImageBrush ImageSource="03.png" Stretch="UniformToFill"/>
- </Polygon.Fill>
- </Polygon>
- <Ellipse Width="130" Height="130" Canvas.Left="245" Canvas.Top="80">
- <Ellipse.Fill>
- <ImageBrush ImageSource="/04.png" Stretch="UniformToFill"/>
- </Ellipse.Fill>
- </Ellipse>
- </Canvas>
- <Button Content="保存图像文件" Grid.Row="1" Click="OnClick"/>
- </Grid>
然后,处理Button的事件,生成图片,保存到相册中的“保存的图片”中。
- private async void OnClick(object sender, RoutedEventArgs e)
- {
- Button b = sender as Button;
- b.IsEnabled = false;
- StorageFolder savedPics = KnownFolders.SavedPictures;
- // 1、在位图中呈现UI元素
- RenderTargetBitmap rtb = new RenderTargetBitmap();
- await rtb.RenderAsync(this.cv);
- // 提取像素数据
- IBuffer buffer = await rtb.GetPixelsAsync();
- // 创建新文件
- StorageFile newFile = await savedPics.CreateFileAsync("test-3-7-11-5.png", CreationCollisionOption.ReplaceExisting);
- // 获取文件流
- IRandomAccessStream streamOut = await newFile.OpenAsync(FileAccessMode.ReadWrite);
- // 实例化编码器
- BitmapEncoder pngEncoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, streamOut);
- // 写入像素数据
- byte[] data = buffer.ToArray();
- pngEncoder.SetPixelData(BitmapPixelFormat.Bgra8,
- BitmapAlphaMode.Straight,
- (uint)rtb.PixelWidth,
- (uint)rtb.PixelHeight,
- 96d, 96d, data);
- await pngEncoder.FlushAsync();
- streamOut.Dispose();
- b.IsEnabled = true;
- }
运行效果如下图
在写入像素数据时,最常用的格式是rgba8或bgra8,一般8位够用了,虽然就是R值和B值的通道顺序不同,但这两种格式所保存的图片文件效果不太一样,我觉得bgra8好一点,没有偏色。
下面是保存后的PNG图片,左边的是用RGBA格式的,右边是用BGRA格式的,大家自行比较吧。
虽然老周的书法水平不怎么样,大家将就着看吧,重点是看RenderTargetBitmap类的用法。
示例下载:http://files.cnblogs.com/tcjiaan/RenderUiApp.zip
好,再次感谢您收看老周吹牛节目,再见。
【WP8.1开发】RenderTargetBitmap类的特殊用途的更多相关文章
- 7.2.3 使用RenderTargetBitmap类生成图片
RenderTargetBitmap类可以将可视化对象转换为位图,也就是说它可以将任意的UIElement以位图的形式呈现.那么我们在实际的编程中通常会利用RenderTargetBitmap类来对U ...
- C# Windows Phone 8 WP8 高级开发,制作不循环 Pivot ,图片(Gallery)导览不求人! 内附图文教学!!
原文:C# Windows Phone 8 WP8 高级开发,制作不循环 Pivot ,图片(Gallery)导览不求人! 内附图文教学!! 一般我们在开发Winodws Phone APP 的时候往 ...
- WP8.1开发:简单天气预报应用(转)
今天小梦给大家分享一个简单的天气预报应用源码:调用的是百度API.整个应用都没有什么难点.只是一个简单的网络请求和json数据处理.在WP8.1有小娜的情况下,天气预报应用还有意义吗?我认为还是有点意 ...
- JAVA串口开发帮助类分享-及写在马年末
摘要: 在系统集成开发过程中,存在着各式的传输途径,其中串口经常因其安全性高获得了数据安全传输的重用,通过串口传输可以从硬件上保证数据传输的单向性,这是其它介质所不具备的物理条件.下面我就串口java ...
- (转载)实例详解Android快速开发工具类总结
实例详解Android快速开发工具类总结 作者:LiJinlun 字体:[增加 减小] 类型:转载 时间:2016-01-24我要评论 这篇文章主要介绍了实例详解Android快速开发工具类总结的相关 ...
- Windows系统开发常用类-------------Environment类
Windows系统开发常用类-------------Environment类: SystemDirectory//显示系统目录 MachineName//计算机名称 ...
- WP8.1开发:简单的天气预报应用
今天小梦给大家分享一个简单的天气预报应用源码:调用的是百度API.整个应用都没有什么难点.只是一个简单的网络请求和json数据处理.在WP8.1有小娜的情况下,天气预报应用还有意义吗?我认为还是有点意 ...
- Java开发工具类集合
Java开发工具类集合 01.MD5加密工具类 import java.security.MessageDigest; import java.security.NoSuchAlgorithmExce ...
- Java,面试题,简历,Linux,大数据,常用开发工具类,API文档,电子书,各种思维导图资源,百度网盘资源,BBS论坛系统 ERP管理系统 OA办公自动化管理系统 车辆管理系统 各种后台管理系统
Java,面试题,简历,Linux,大数据,常用开发工具类,API文档,电子书,各种思维导图资源,百度网盘资源BBS论坛系统 ERP管理系统 OA办公自动化管理系统 车辆管理系统 家庭理财系统 各种后 ...
随机推荐
- CentOS6.5的vsftp搭建流程(一)
前几次搭建FTP都失败了,不是登陆不了,就是目录没有权限.现在终于摸索出了靠谱的操作流程,分享之~ 1. 查看是否安装了vsftpd,未安装则安装 [root@iZ283tian2dZ /]# rpm ...
- ACM :漫漫上学路 -DP -水题
CSU 1772 漫漫上学路 Time Limit: 1000MS Memory Limit: 131072KB 64bit IO Format: %lld & %llu Submit ...
- Android开发 SQLite数据库应用笔记(一)
注意: 1.public Cursor rawQuery(String sql, String[] selectionArgs) Cursor游标是查询后返回的结果集合,游标的意思是指向集合中的某行. ...
- js学习笔记
javacript笔记根据EC5.0一共有六种数据类型:number,string,bool undefine,nullobject(广义的) --->object(狭义的),array,fun ...
- POJ 1163 The Triangle(简单动态规划)
http://poj.org/problem?id=1163 The Triangle Time Limit: 1000MS Memory Limit: 10000K Total Submissi ...
- Odoo 二次开发教程(四)-只读、唯一性验证和ORM方法介绍
一.只读和唯一性验证 只读的设置有两种方法,一种是实在字段定义时设置为只读,第二种是在页面视图中进行设置. 接前例,我们将学生(tech.student)的名字name字段设置成只读. 方法一:字段定 ...
- .net 文件上传大小的设置
直接在配置文件web.config 中进行如下配置,主要需要明白的就是 配置的 单位是 Byte, 所以一定计算清楚,不然会在这里纠结很久!!! <configuration> < ...
- php获取excel所有的批注
phpexcel下载:https://github.com/PHPOffice/PHPExcel <?php /** *获取excel所有的批注 * * 存在编码问题,xls和xlsx的批注编码 ...
- 游戏编程技巧 - Type Object
Type Object 使用场景 你在制作一款和LOL类似的游戏,里面有许多英雄,因此你想建立一个英雄基类,然后把各种英雄都继承自该基类,这些英雄类都有生命值和攻击力等属性.每次策划想增加一个英雄,你 ...
- java 多线程 继承Thread和实现Runnable的区别
1)继承Thread: public class ThreadTest extends Thread { private int count; private String name; public ...