相信,耍过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类的特殊用途的更多相关文章

  1. 7.2.3 使用RenderTargetBitmap类生成图片

    RenderTargetBitmap类可以将可视化对象转换为位图,也就是说它可以将任意的UIElement以位图的形式呈现.那么我们在实际的编程中通常会利用RenderTargetBitmap类来对U ...

  2. C# Windows Phone 8 WP8 高级开发,制作不循环 Pivot ,图片(Gallery)导览不求人! 内附图文教学!!

    原文:C# Windows Phone 8 WP8 高级开发,制作不循环 Pivot ,图片(Gallery)导览不求人! 内附图文教学!! 一般我们在开发Winodws Phone APP 的时候往 ...

  3. WP8.1开发:简单天气预报应用(转)

    今天小梦给大家分享一个简单的天气预报应用源码:调用的是百度API.整个应用都没有什么难点.只是一个简单的网络请求和json数据处理.在WP8.1有小娜的情况下,天气预报应用还有意义吗?我认为还是有点意 ...

  4. JAVA串口开发帮助类分享-及写在马年末

    摘要: 在系统集成开发过程中,存在着各式的传输途径,其中串口经常因其安全性高获得了数据安全传输的重用,通过串口传输可以从硬件上保证数据传输的单向性,这是其它介质所不具备的物理条件.下面我就串口java ...

  5. (转载)实例详解Android快速开发工具类总结

    实例详解Android快速开发工具类总结 作者:LiJinlun 字体:[增加 减小] 类型:转载 时间:2016-01-24我要评论 这篇文章主要介绍了实例详解Android快速开发工具类总结的相关 ...

  6. Windows系统开发常用类-------------Environment类

    Windows系统开发常用类-------------Environment类:         SystemDirectory//显示系统目录         MachineName//计算机名称 ...

  7. WP8.1开发:简单的天气预报应用

    今天小梦给大家分享一个简单的天气预报应用源码:调用的是百度API.整个应用都没有什么难点.只是一个简单的网络请求和json数据处理.在WP8.1有小娜的情况下,天气预报应用还有意义吗?我认为还是有点意 ...

  8. Java开发工具类集合

    Java开发工具类集合 01.MD5加密工具类 import java.security.MessageDigest; import java.security.NoSuchAlgorithmExce ...

  9. Java,面试题,简历,Linux,大数据,常用开发工具类,API文档,电子书,各种思维导图资源,百度网盘资源,BBS论坛系统 ERP管理系统 OA办公自动化管理系统 车辆管理系统 各种后台管理系统

    Java,面试题,简历,Linux,大数据,常用开发工具类,API文档,电子书,各种思维导图资源,百度网盘资源BBS论坛系统 ERP管理系统 OA办公自动化管理系统 车辆管理系统 家庭理财系统 各种后 ...

随机推荐

  1. kindeditor-4.1.3工具使用技巧:如何在编辑区上传图片并保存绝对路径

    MVC项目开中用到了KindEditor图片上传工具,需要在编辑区内上传图片,并将图片的URL保存为符合如下格式地址,如http://192.168.0.111/uploadImg/imgName.j ...

  2. 【生活没有希望】hdu1166敌兵布阵 线段树

    线段树水题刷刷,生活没有希望 最近看到代码跟树状数组差不多短的非递归线段树,常数也很小——zkw线段树 于是拿道水题练练手 短到让人身无可恋 ;pos;pos/=) a[pos]+=x;} ,ans= ...

  3. zookeeper工作原理、安装配置、工具命令简介

    1.Zookeeper简介 Zookeeper 是分布式服务框架,主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务.状态同步服务.集群管理.分布式应用配置项的管理等等. 2.zo ...

  4. 使用Python中PIL图形库进行截屏

    目的:通过使用Python的一个图形库PIL(Python Image Library)对屏幕进行截图 步骤: 1.下载PIL(路径)并安装 2.新建文件“截屏.py”,右键Edit with IDL ...

  5. Hibernate多对多双向关联的配置

    Hibernate的双向多对多关联有两种配置方法:那我们就来看看两种方案是如何配置的.  一.创建以各自类为类型的集合来关联 1.首先我们要在两个实体类(雇员<Emploee>.工程< ...

  6. java并发之volatile

    volatile是轻量级的synchronized,它在多处理器应用开发中保证了共享变量的“可见性”(可见性指当一个线程修改共享变量后,其它线程可以看到这个修改). volatile如果使用合理会比s ...

  7. Oracle数据库操作

    本例使用oracle数据库,使用PL/SQL可视化工具: --查询员工表数据 (emp为pl/sql自带的表,也可自己新建)select * from emp; --创建表空间create table ...

  8. [CSS]textarea设置下划线格式

    功能要求:1:如何实现在多行文本框textarea里面每一行下面都有一条横线  2:textarea文本框里面有一段不能删掉 实现方法:横线用背景图片来做,不动的文字用浮动层+给textarea增加t ...

  9. WPF整理-二进制资源和内容

    WPF中的Binary Resource(二进制资源)是相对于前面所说的Logical resource(逻辑资源)而说的,一般指Image.XML文件等. 注意:这里说的是Resource" ...

  10. 跟服务器交互的登录Demo

    服务器写死 账号密码,演示登录 服务器代码: 开发工具MyEclipse public class LoginServlet extends HttpServlet { /** * The doGet ...