0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Android高效内存:让图片占用尽可能少的内存

Dbwd_Imgtec 来源:未知 作者:胡薇 2018-06-02 11:05 次阅读

在做内存优化的时候,我们发现除了解决内存泄露问题,剩下的就只有想办法减少真实的内存占用。而在App中,大部分内存可能被我们图片占用了,所以减少图片的内存占用可以带来直接的效果。

一、一张图片到底占用多少内存

我们先假设我们有一张图片是600 * 800像素的,图片磁盘占用空间大小假设是 100KB。

图片内存大小跟磁盘占用空间大小有什么关系?

磁盘占用空间的大小不是图片占用内存的大小,磁盘占用空间是在磁盘上存储图片需要的一个空间大小,内存大小是加载到内存中占用的内存大小。两个只是单位是一样的,本质不是一个概念。

一张图片到底占用多少内存呢?

图片占用内存的计算公式是:图片高度 * 图片宽度 * 一个像素占用的内存大小,在Android中一般情况下默认一个像素占用内存是4个字节,所以上面的图片占用内存是:800 * 600 * 4 byte = 1875KB = 1.83M。为什么是4个字节呢?一定是4个字节么?这两个问题后面仔细讲。

图片所在目录对内存的影响?

在Android中,图片的存放目录和手机的屏幕密度影响图片最终加载到内存的实际大小,举个例子:假设我们的图片放到xhdpi目录下,那么我们本文中的图片占用的内存大小如下:

屏幕密度为2的设备:800 * 600 * 4byte = 1.83M

屏幕密度为3的设备:800 * 1.5 * 600 * 1.5 * 4byte = 1.83 * 2.25M = 4.12M

这里所说的屏幕密度是指android.util.DisplayMetrics类中的density变量,是一个float值,关于屏幕密度的更多内容本文不做介绍。

所以,计算图片占用内存大小的时候,要考虑图片所在的目录跟屏幕密度,这两个因素其实影响的是图片的高宽,Android会对图片进行拉升跟压缩。

二、 让你的图片省内存

2.1 让你的图片最小化

图片的内存占用计算方式为:图片高度 * 图片宽度 * 一个像素占用的内存大小,所以图片的高宽如果都变为原来宽高的2倍,那么内存将变为原来的4倍。所以图片的使用原则可以总结如下:

使用尽可能小的图

使用.9图,.9图本身也要尽可能的小

自己绘制(覆写View的onDraw自己画)或者使用Drawable来绘制

比如要实现一个线性渐变效果可以采用以下drawable实现:

2.2 在内存中压缩图片

加载大图片时需要对图片进行压缩,使用等比例压缩方法直接在内存中处理图片。

这样做要注意的是,图片质量会变差,inSampleSize设置的值越大,图片质量就越差。

2.3 读取位图尺寸和类型时不把图片加载到内存中

有时候我们取得一张图片,也许只是为了获得这个图片的一些信息,比如图片的width、height等信息,不需要显示到界面上,这个时候我们可以不把图片加载到内存中。

2.4 用完就回收

由于Android外层是使用java,而底层使用的是C语言为图片对象分配的内存空间。所以我们的外部虽然看起来释放了,但里层却并不一定完全释放了,我们使用完图片后最好再释放掉里层的内存空间。

2.5 降低要显示的图片色彩质量

2.5.1 颜色模型

RGB(ARGB)

RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。在Android中还有包含透明度Alpha的颜色模型,即ARGB。

2.5.2 RGB在计算机中颜色值的数字化编码

在不考虑透明度的情况下,一个像素点的颜色值在计算机中的表示方法有以下3种:

浮点数编码:比如float: (1.0, 0.5, 0.75),每个颜色分量各占1个float字段,其中1.0表示该分量的值为全红或全绿或全蓝。

24位的整数编码:比如24-bit:(255, 128, 196),每个颜色分量各占8位,取值范围0-255,其中255表示该分量的值为全红或全绿或全蓝。

16位的整数编码:比如16-bit:(31, 45, 31),第1和第3个颜色分量各占5位,取值范围0-31,第2个颜色分量占6位,取值范围0-63。

在Java中,float类型的变量占32位,int类型的变量占32位,short和char类型的变量都在16位,因此可以看出,用浮点数表示法编码一个像素的颜色,内存占用量是96位即12字节;而用24位整数表示法编码,只要一个int类型变量,占用4个字节(高8位空着,低24位用于表示颜色);用16位整数表示法编码,只要一个short类型变量,占2个字节;因此可以看出采用整数表示法编码颜色值,可以大大节省内存,当然,颜色质量也会相对低一些。在Android中获取Bitmap的时候一般也采用整型编码。

2.5.3 Android中RGB编码格式(整型编码)

RGB888(int):R、G、B分量各占8位

RGB565(short):R、G、B分量分别占5、6、5位

RGB555(short):RGB分量都用5位表示(剩下的1位不用)

ARGB8888(int):A、R、G、B分量各占8位

ARGB4444(short):A、R、G、B分量各占4位

在Android的Bitmap.Config类中,有ARGB_8888、ARGB_4444、RGB565等常量,现在可以知道它们分别代表了什么含义。

在Android中系统默认使用的编码格式是ARGB_8888,所以在文章开头计算图片内存大小的时候每个像素占用内存大小是4byte,比如采用ARGB_8888编码载入一张1920*1200的图片,大概就会占用1920*1200*4/1024/1024=8.79MB的内存。

2.5.4 降低要显示的图片色彩质量

采用低内存占用量的编码方式,比如Bitmap.Config.ARGB_4444比Bitmap.Config.ARGB_8888更省内存,比如1920*1200的图片。

ARGB_8888:1920*1200*4/1024/1024=8.79MB

ARGB_4444,RGB565:1920*1200*2/1024/1024=4.39MB

三、总结

在Android中,对图片的使用一定要关注,大多数情况下,占用内存多,OOM发生都是因为图片资源使用不当。不要盲目加一个大图到Android项目中,能使用.9进来使用,而且.9图本身尽可能小,另外能使用绘制实现就不要加一个图片资源。有些时候,在不影响用户体验的情况下,可以降低图片色彩质量,比如不需要透明度的就不要了,有些透明度用肉眼看不出来。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Android
    +关注

    关注

    12

    文章

    3917

    浏览量

    127027
  • 内存
    +关注

    关注

    8

    文章

    2964

    浏览量

    73804

原文标题:Android高效内存之让你的图片省内存

文章出处:【微信号:Imgtec,微信公众号:Imagination Tech】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    内存管理学习笔记分享

    物理内存分配设计有两个重要的评价维度。一方面,物理内存分配器要追求更高的内存资源利用率,即尽可能减少资源浪费。另一方面,物理内存分配器要追求
    的头像 发表于 01-06 14:53 1656次阅读

    Linux内核内存规整总结

    1.前言 伙伴系统作为内核最基础的物理页内存分配器,具有高效、实现逻辑简介等优点,其原理页也尽可能降低内存外部碎片产生,但依然无法杜绝碎片问题。外部碎片带来的最大影响就是
    的头像 发表于 11-11 11:17 1249次阅读
    Linux内核<b class='flag-5'>内存</b>规整总结

    五大方法内存使用更高效

    、文件或窗口。有些应用程序不能用一般的方法关闭,这时就要进行热启动,如按下“CTRL+ALT+DEL”;另外要注意剪贴板中如果存储了一幅图片或图像,图片或图像是要占用大量内存的,这时只
    发表于 01-02 23:46

    labview的内存问题

    如图所示为,图像处理一个图像的过程,按照道理这种图片的大小为43.3MB,可是观察VI运行时候的内存占用大小,如果没有VI运行至最后,那么vi占用
    发表于 09-18 21:20

    如何确保尽可能高效地测试开关稳压器?

    问题:如何确保尽可能高效地测试开关稳压器?
    发表于 03-01 08:50

    缓冲VDAC输出损失如何尽可能的减少?

    ,但是连接后电压不会下降到1.9V以下。JRK直接从电位器工作。我想在PSoC和控制器之间放置一个运放来缓冲这个,但是我想尽可能的损失,尽可能地保持输出的精确性。我需要一个DIL包,这样我就可以剥离
    发表于 10-08 12:43

    解码会占用多少内存?使用vpp进行图像处理最大可能会消耗多少内存

    解码会占用多少内存?使用vpp进行图像处理,最大可能会消耗多少内存
    发表于 09-19 07:24

    DDR内存接口的设计与实现

    针对当今电子系统对高速大容量内存的需要,本文阐述了使用DDR 控制器IP 核来设计实现DDR内存接口的方法。该方法能使设计尽可能简单,设计者更专注于关键逻辑设计,以便达到
    发表于 08-11 09:42 21次下载

    Android应用程序内存泄漏的原因及规避方法

    引言 Android应用程序中内存使用的问题经常容易被忽视,在传统的编程语言中(例如C语言),回收内存的任务是由程序本身来完成的,程序可以显式分配和释放变量所占用
    发表于 10-19 14:52 0次下载
    <b class='flag-5'>Android</b>应用程序<b class='flag-5'>内存</b>泄漏的原因及规避方法

    基于Android系统的高效内存方法解析

    在做内存优化的时候,我们发现除了解决内存泄露问题,剩下的就只有想办法减少真实的内存占用。而在App中,大部分内存
    发表于 06-05 20:23 1150次阅读

    设计全定制ASIC以占用尽可能多的硅面积变得越来越具有挑战性

    “设计重用”是将高质量知识产权(IP)从一种ASIC设计迁移到另一种ASIC设计的过程。随着半导体技术的巨大进步,越来越难以弥合技术提供与硅生产率允许之间的生产率差距。设计全定制ASIC以占用尽可能
    的头像 发表于 08-13 17:02 1801次阅读

    Java服务器内存和CPU占用过高的原因

    造成服务器内存占用过高只有两种情况:内存溢出或内存泄漏
    的头像 发表于 03-21 15:50 2.2w次阅读

    电脑内存占用过高加内存条起作用吗

    电脑内存占用过高加内存条有用。内存容量小是内容占用过高的其中一个原因,所以加内存条可以解决问题;
    发表于 06-16 10:25 6588次阅读

    更低内存占用的通用Json库-RyanJson

    RyanJson是一个小巧的c语言json解析器,包含json文本文件解析 / 生成,专门针对内存占用进行优化,相比cJSON内存占用减少30% - 60%,运行速度和cJSON差不多
    的头像 发表于 08-24 17:23 1540次阅读
    更低<b class='flag-5'>内存</b><b class='flag-5'>占用</b>的通用Json库-RyanJson

    Windows不明内存占用案例分析:Driver Locked

    前一段有客户反映Windows系统下不明内存占用越来越多,128GB物理内存的主机,启动完成后就有大约一半的内存占用,导致留给应用的
    的头像 发表于 09-25 14:49 1724次阅读
    Windows不明<b class='flag-5'>内存</b><b class='flag-5'>占用</b>案例分析:Driver Locked