跟图片打交道的 UWP 应用或多或少都会遇到图片带来的性能问题,就算不主要处理图片,做个论坛做个新闻客户端都涉及到大量图片。一个帖子、一篇文章里多半都是些高清大图,这些图片一张即可占用程序 1~2M 的内存空间。普通的写法内存很快就爆了,那么 UWP 中我们可以用哪些方法优化呢?


1. DecodePixelWidth/DecodePixelHeight

对于那些高分辨率图像,直接设置其 DecodePixelWidthDecodePixelHeight 的值为较小的值即可大大节省内存空间。以下两种方法中,后者对内存空间的节省非常显著。

<!-- 性能不好 -->
<Image Source="ms-appx:///Assets/high-resolution-image.jpg"
Width="300" Height="200"/>
<!-- 性能不错 -->
<Image>
<Image.Source>
<BitmapImage UriSource="ms-appx:///Assets/high-resolution-image.jpg"
DecodePixelWidth="300" DecodePixelHeight="200"/>
</Image.Source>
</Image>

2. 利用好自带的布局机制

如果没有指定 DecodePixelWidth/DecodePixelHeight,那么 XAML 会根据布局自动调整图片的解码大小。

不过,微软才不会让你这么开心地就用!如果你做了这些事,就当布局自带的内存优化不存在好了:

  1. 你先调了 SetSourceAsync 或设置了 UriSource,然后才把 BitmapImage 连接到活动的 XAML 树
  2. 使用异步解码(如 SetSource)解码图像。
  3. 把图像或父控件的 Opacity 设成了 0,或者 Visibility 设为 Collapsed
  4. ImageBrushStrech 设成了 None
  5. 图像用作点九图(参见 NineGrid
  6. 给图像或父控件设置了 CacheMode="BitmapCache"
  7. ImageBrush 绘制到不是矩形的地方 (试过画到文字上或形状上吗?)

关于第 1 条,这里有一些官方的代码作为例子:

<!-- 推荐写法,直接在 XAML 里指定 UriSoruce -->
<Image x:Name="myImage" UriSource="Assets/cool-image.png"/>
<!-- 但如果没有在 XAML 中指定,也可以去后台代码指定。 -->
<Image x:Name="myImage"/>
// 后台代码如果这样写就不错,因为先把 BitmapImage 放到了活动的 XAML 树上。
var bitmapImage = new BitmapImage();
myImage.Source = bitmapImage;
bitmapImage.UriSource = new URI("ms-appx:///Assets/cool-image.png", UriKind.RelativeOrAbsolute);
// 然而这样写就不太推荐了,因为先设置了 UriSource,再把 BitmapImage 放到活动的 XAML 树上。
var bitmapImage = new BitmapImage();
bitmapImage.UriSource = new URI("ms-appx:///Assets/cool-image.png", UriKind.RelativeOrAbsolute);
myImage.Source = bitmapImage;

3. 利用好自带的缓存机制

如果你用 UriSource 属性,那么恭喜,你将获得自带的图片缓存!如果多次使用相同的 Uri,那么会共用同一份内存空间。除此之外就没啦,比如自己创建一个流啊什么的;这就是说并不建议自己用 FileStream

另外,微软提供了这么好用的 SetSourceAsync,但是用了这个就没有缓存了!于是我到底是用还是不用呢?

4. GetThumbnailAsync

如果你使用本机文件,那么恭喜,你直接获得了拿到系统自带缩略图的机会!

使用系统自带的缩略图比前面的方法都更好,因为如果系统已经生成好了缩略图,你根本连解码图像都不需要。

FileOpenPicker picker = new FileOpenPicker();
picker.FileTypeFilter.Add(".bmp");
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".jpeg");
picker.FileTypeFilter.Add(".png");
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary; StorageFile file = await picker.PickSingleFileAsync(); StorageItemThumbnail fileThumbnail = await file.GetThumbnailAsync(ThumbnailMode.SingleItem, 64); BitmapImage bmp = new BitmapImage();
bmp.SetSource(fileThumbnail); Image img = new Image();
img.Source = bmp;

关于 GetThumbnailAsync 的详细用法,我的好朋友林德熙有更详细的说明,参见:win10 uwp 获得缩略图

优化 UWP 中图片的内存占用的更多相关文章

  1. [转帖]Linux中buff/cache内存占用过高解决办法

    Linux中buff/cache内存占用过高解决办法 https://www.cnblogs.com/rocky-AGE-24/p/7629500.html /proc/sys/vm/drop_cac ...

  2. 项目中Map端内存占用的分析

      最近在项目中开展重构活动,对Map端内存尽量要省一些,当前的系统中Map端内存最高占用大概3G左右(设置成2G时会导致Java Heap OOM).虽然个人觉得占用不算多,但是显然这样的结果想要试 ...

  3. 使用ExpandableListView以及如何优化view的显示减少内存占用

    上篇博客讲到如何获取手机中所有歌曲的信息.本文就把上篇获取到的歌曲按照歌手名字分类.用一个ExpandableListView显示出来. MainActivity .java   public cla ...

  4. Linux中buff/cache内存占用过高解决办法

    在Linux系统中,我们经常用free命令来查看系统内存的使用状态.在一个centos7的系统上,free命令的显示内容大概是这样一个状态: 这个命令几乎是每一个使用过Linux的人必会的命令,但越是 ...

  5. C#中XmlSerializer的内存占用问题

    被XmlSerializer掉坑里了,爬了一晚上才出来. 本来实现一个功能,从数据库中查出一堆数据(比较多,几十万,不过,是分批查出来的),查出来的数据包含了一个XML字符串,代码中对其进行序列化,一 ...

  6. Linux 中 Buffer/Cache内存占用过高解决方法

    在Linux系统中,我们经常用free命令来查看系统内存的使用状态.在一个RHEL6的系统上,free命令的显示内容大概是这样一个状态: 这里的默认显示单位是kb,我的服务器是128G内存,所以数字显 ...

  7. SqlServer性能优化,查看CPU、内存占用大的会话及SQL语句

    1,查看CPU占用量最高的会话及SQL语句   select spid,cmd,cpu,physical_io,memusage, (select top 1 [text] from ::fn_get ...

  8. 关于Android应用中图片占用内存浅谈

    从事过移动端应用开发的童鞋应该都清楚,内存是非常宝贵的资源.如果能很好的利用有限的内存,对应用性能的提升会有很大的帮助.在实际应用开发中图片内存占整个应用非常大的比重,我们只有了解图片是如何加载到内存 ...

  9. Android性能优化之利用LeakCanary检测内存泄漏及解决办法

    前言: 最近公司C轮融资成功了,移动团队准备扩大一下,需要招聘Android开发工程师,陆陆续续面试了几位Android应聘者,面试过程中聊到性能优化中如何避免内存泄漏问题时,很少有人全面的回答上来. ...

随机推荐

  1. C和C#两种方式实现邮件的简单接收

    本文的主要内容是通过两种方式实现简单邮件的接收,一种方式是通过C语言实现,另一种是通过C#实现的, 两种方式在实现上有许多的不同之处,但是本质上都是一样的. 一,C语言实现方式 C语言接收邮件的步骤: ...

  2. Java程序员怎么迈向架构师

    怎样学习才能从一名Java初级程序员成长为一名合格的架构师,或者说一名合格的架构师应该有怎样的技术知识体系,这是不仅一个刚刚踏入职场的初级程序员也是工作三五年之后开始迷茫的老程序员经常会问到的问题. ...

  3. [sping]xml配置文件中factory-bean与factory-method(spring使用工厂方法注入bean)

    public class CarFactory { //非静态方法 public Car createCar(){ Car car = new Car(); car.setBrand("BM ...

  4. JSON 参考文档

    1.JSON字符串转换为JSON对象 var obj = JSON.parse(str); 2.JSON对象转化为JSON字符串 var str = JSON.stringify(obj); 对此有一 ...

  5. 微信小程序------小程序初步学习

    1:学习微信小程序,首先的会一点前端的基础会比较容易上手,比如:HTML+CSS,JS,HTML5+CSS3: H5+CSS3中的弹性盒子在微信小程序中经常用到,这是必须掌握的.不会的可以去W3C文档 ...

  6. Gruntjs提高生产力(三)

    以下例子来自真实项目,有所删减 grunt-test project 目录结构如下 一我的目的: 1.在src-dev目录中开发最终产出于src目录 2.src-dev中的index目录相当于一个wi ...

  7. iptables详解(13):iptables动作总结之二

    概述 阅读这篇文章需要站在前文的基础上,如果你在阅读时遇到障碍,请参考之前的文章. 前文中,我们已经了解了如下动作 ACCEPT.DROP.REJECT.LOG 今天,我们来认识几个新动作,它们是: ...

  8. TLS就是SSL的升级版+网络安全——一图看懂HTTPS建立过程——本质上就是引入第三方监管,web服务器需要先生成公钥和私钥,去CA申请,https通信时候浏览器会去CA校验CA证书的有效性

    起初是因为HTTP在传输数据时使用的是明文(虽然说POST提交的数据时放在报体里看不到的,但是还是可以通过抓包工具窃取到)是不安全的,为了解决这一隐患网景公司推出了SSL安全套接字协议层,SSL是基于 ...

  9. JS之BOM和DOM(来源、方法、内容、应用)

    1.Javascript组成(此文为转载) JavaScript的实现包括以下3个部分: 1)核心(ECMAScript):描述了JS的语法和基本对象. 2)文档对象模型 (DOM):处理网页内容的方 ...

  10. 内存保护机制及绕过方法——通过覆盖部分地址绕过ASLR

    ASLR保护机制 ASLR简介 微软在Windows Vista.2008 server.Windows 7.Windows 8等系统的发布中, 开始将ASLR作为内置的系统保护机制运行, 将系统映像 ...