优化 UWP 中图片的内存占用
跟图片打交道的 UWP 应用或多或少都会遇到图片带来的性能问题,就算不主要处理图片,做个论坛做个新闻客户端都涉及到大量图片。一个帖子、一篇文章里多半都是些高清大图,这些图片一张即可占用程序 1~2M 的内存空间。普通的写法内存很快就爆了,那么 UWP 中我们可以用哪些方法优化呢?
1. DecodePixelWidth/DecodePixelHeight
对于那些高分辨率图像,直接设置其 DecodePixelWidth 和 DecodePixelHeight 的值为较小的值即可大大节省内存空间。以下两种方法中,后者对内存空间的节省非常显著。
<!-- 性能不好 -->
<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 会根据布局自动调整图片的解码大小。
不过,微软才不会让你这么开心地就用!如果你做了这些事,就当布局自带的内存优化不存在好了:
- 你先调了
SetSourceAsync或设置了UriSource,然后才把BitmapImage连接到活动的 XAML 树 - 使用异步解码(如
SetSource)解码图像。 - 把图像或父控件的
Opacity设成了 0,或者Visibility设为Collapsed ImageBrush的Strech设成了None- 图像用作点九图(参见 NineGrid)
- 给图像或父控件设置了
CacheMode="BitmapCache" 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 中图片的内存占用的更多相关文章
- [转帖]Linux中buff/cache内存占用过高解决办法
Linux中buff/cache内存占用过高解决办法 https://www.cnblogs.com/rocky-AGE-24/p/7629500.html /proc/sys/vm/drop_cac ...
- 项目中Map端内存占用的分析
最近在项目中开展重构活动,对Map端内存尽量要省一些,当前的系统中Map端内存最高占用大概3G左右(设置成2G时会导致Java Heap OOM).虽然个人觉得占用不算多,但是显然这样的结果想要试 ...
- 使用ExpandableListView以及如何优化view的显示减少内存占用
上篇博客讲到如何获取手机中所有歌曲的信息.本文就把上篇获取到的歌曲按照歌手名字分类.用一个ExpandableListView显示出来. MainActivity .java public cla ...
- Linux中buff/cache内存占用过高解决办法
在Linux系统中,我们经常用free命令来查看系统内存的使用状态.在一个centos7的系统上,free命令的显示内容大概是这样一个状态: 这个命令几乎是每一个使用过Linux的人必会的命令,但越是 ...
- C#中XmlSerializer的内存占用问题
被XmlSerializer掉坑里了,爬了一晚上才出来. 本来实现一个功能,从数据库中查出一堆数据(比较多,几十万,不过,是分批查出来的),查出来的数据包含了一个XML字符串,代码中对其进行序列化,一 ...
- Linux 中 Buffer/Cache内存占用过高解决方法
在Linux系统中,我们经常用free命令来查看系统内存的使用状态.在一个RHEL6的系统上,free命令的显示内容大概是这样一个状态: 这里的默认显示单位是kb,我的服务器是128G内存,所以数字显 ...
- SqlServer性能优化,查看CPU、内存占用大的会话及SQL语句
1,查看CPU占用量最高的会话及SQL语句 select spid,cmd,cpu,physical_io,memusage, (select top 1 [text] from ::fn_get ...
- 关于Android应用中图片占用内存浅谈
从事过移动端应用开发的童鞋应该都清楚,内存是非常宝贵的资源.如果能很好的利用有限的内存,对应用性能的提升会有很大的帮助.在实际应用开发中图片内存占整个应用非常大的比重,我们只有了解图片是如何加载到内存 ...
- Android性能优化之利用LeakCanary检测内存泄漏及解决办法
前言: 最近公司C轮融资成功了,移动团队准备扩大一下,需要招聘Android开发工程师,陆陆续续面试了几位Android应聘者,面试过程中聊到性能优化中如何避免内存泄漏问题时,很少有人全面的回答上来. ...
随机推荐
- ASP.NET 中 POST 数据并跳转页面(译自 Redirect and POST in ASP.NET)
本文翻译自 Samer Abu Rabie 的 <Redirect and POST in ASP.NET> 简介 在实际项目中,我们会遇到这样一种应用场景:我们需要与第三方 ...
- Python基础笔记系列十:模块
本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! 模块 #1.类比于java中的jar包,模块能让你能够有逻辑地组织你的Py ...
- js添加事件 attachEvent 和addEventListener的用法
一般我们在JS中添加事件,是这样子的: obj.onclick = method 这种绑定事件的方式,兼容主流浏览器,但是如果一个元素上添加多次同一个事件呢??? obj.onclick = meth ...
- docker教程目录
为什么要用 Docker 什么是 Docker Docker 镜像 Docker容器的运用 Docker仓库 Docker如何获取镜像 CentOS 安装Docker Docker 列出镜像 Dock ...
- Hive -hivevar 参数传递
命令行模式,或者说目录模式,可以使用hive 执行命令. 选项说明: -e : 执行短命令 -f : 执行文件(适合脚本封装) -S : 安静模式,不显示MR的运行过程 -hivevar : 传参数 ...
- 卡在了“正在设定 ttf-mscorefonts-installer”的解决
方向键啊鼠标的都不行,其实用tab键就可以选择了.冏死--
- macOS和常用命令
macOS 常用命令 1. 显示“任何来源”选项 sudo spctl --master-disable 2. 阻止屏保和睡眠 caffeinate -t 3600 这是一个BSD命令.-t可选,按C ...
- HDU-2196-树形dp/计算树上固定起点的最长路
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- Ubuntu 下Python 环境问题
问题描述: 原先使用Anaconda环境,若卸载后仍不能恢复到系统默认的Python环境. 解决方案: shell 寻找缓存路径,python的扩展/home/tom/anaconda/bin/pyt ...
- 在阿里云服务器上配置CentOS+Nginx+Python+Flask环境
在阿里云服务器上配置CentOS+Nginx+Python+Flask环境 项目运行环境 阿里云(单核CPU, 1G内存, Ubuntu 14.04 x64 带宽1Mbps), 具体购买和ssh连接阿 ...