跟图片打交道的 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. spring-boot 加入拦截器Interceptor

    1.spring boot拦截器默认有 HandlerInterceptorAdapter AbstractHandlerMapping UserRoleAuthorizationIntercepto ...

  2. ThinkPHP开发笔记-用户登录注册

    1.修改模块配置,Application/当前模块名/Conf/config.php <?php return array( //数据库配置信息 'DB_TYPE' => 'mysql', ...

  3. CGI-FASTCGI-PHPFPM

    随意记录,摘自知乎 原文链接:https://segmentfault.com/q/1010000000256516 首先,CGI是干嘛的?CGI是为了保证web server传递过来的数据是标准格式 ...

  4. vue-router的一个小实例

    非2.0的 vue2.0还有vue-router2.0的改变还是挺大的 vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用.vue的单页面应用是基于 ...

  5. rdlc报表出现多余空白页面

    1.RDLC报表设计好后,在ReportViewer预览报表时,页数都正常:但在切换为整页模式时,常造成多了不少空白页出来.第一时间觉得不可思议,在ReportViewer看来正常,怎可能在整页预览时 ...

  6. 1-13 RHEL7-硬盘介绍和磁盘管理

    熟悉Linux平台下的存储介质,LVM逻辑卷.RAID 磁盘陈列等 大纲: 1-1  硬盘的分类及使用fdisk分区工具       1-1-1 认识硬盘的分类和特性.SCSI.IDE.SAS.SAT ...

  7. NVML查询显卡信息

    前段时间做英伟达硬解得时候,显卡总是莫名挂掉,后来发现是因为显卡温度过高掉了.这几天找到CUDA中有NVML工具可以查看显卡信息,nvidia-smi也是基于这个工具包. 使用的CUDA版本为CUDA ...

  8. MongoHelper.cs

    using System; using MongoDB.Bson; using MongoDB; using System.Web; using MongoDB.Driver; namespace Y ...

  9. python中“生成器”、“迭代器”、“闭包”、“装饰器”的深入理解

    一.生成器 1.什么是生成器? 在python中,一边循环一边计算的机制,称为生成器:generator. 2.生成器有什么优点? 1.节约内存.python在使用生成器时对延迟操作提供了支持.所谓延 ...

  10. py2exe生成.exe(python3.4 尝试)

    第一次成功将python3.4脚本生成 exe文件. 测试环境:win8.1 32位,python3.4,pyside py打包成exe的工具我所知道的有三种 cx-freeze , py2exe , ...