Android中drawable或mipmap文件夹存放图片的区别(详细解释)

2023-05-16

1 问题背景

当在Android Studio来新建一个Android项目,该项目有如下的目录结构:
在这里插入图片描述
Android项目的某个模块中的res文件夹下,有很多以drawable或mipmap开头的子文件夹,这些子文件夹都是用来存储图片的,那么他们之间有什么区别呢?

2 Android中drawable或mipmap文件夹存放图片的区别

2.1 结论

先说结论:应用图标的图片资源存放在mipmap系列文件夹中,而其余图片存放在drawable系列文件夹中

2.2 Android官方对drawable和mipmap文件夹用途的描述

drawable文件夹存储bitmap文件(png, jpeg, gif),9-patch文件和xml文件,这些文件用于描述包含多种状态(normal, pressed, focused)的可绘制形状或可绘制对象。

mipmap文件夹用于存放APP的icon图标文件。Android系统会保留这个文件夹中所有的图片资源,而不受到应用安装的设备的屏幕分辨率的影响。这个行为允许启动程序为应用选择最好的分辨率图标显示在主屏幕上。

2.3 mipmap的定义——什么是mipmap

在三维计算机图形的贴图渲染过程中有一个常用的技术被称为Mipmapping。为了加快渲染速度和减少图像锯齿,贴图被处理成由一系列被预先计算和优化过的图片组成的文件,这样的贴图被称为 MIP map 或者 mipmap。这个技术在三维游戏中被非常广泛的使用。“MIP”来自于拉丁语 multum in parvo 的首字母,意思是“放置很多东西的小空间”,而mipmap中的map有铺设、贴图的意思。

Mipmap中每一个层级的小图都是主图的一个特定比例的缩小细节的复制品。虽然在某些必要的视角,主图仍然会被使用来渲染完整的细节。但是当贴图被缩小或者只需要从远距离观看时,mipmap就会转换到适当的层级,此时mipmap贴图需要被读取的像素远少于普通贴图,所以渲染的速度得到了提升。而且操作的时间减少了,因为mipmap的图片已经是做过抗锯齿处理的,从而减少了实时渲染的负担。放大和缩小也因为mipmap而变得更有效率。

如果某张mipmap贴图的基本尺寸是256x256像素且长宽特定缩放比例为2,该mipmap贴图就会有8个层级。每个层级是上一层级的四分之一的大小,依次层级大小就是:128x128;64x64;32x32;16x16;8x8;4x4;2x2;1x1(一个像素)。

下图是一个mipmap 如何储存的例子,左边的主图伴有一系列逐层缩小的备份小图:

在这里插入图片描述

2.4 Android中mipmap的应用场景

在绝大部分安卓设备的Launcher桌面中,打开或关闭一个APP会有APP打开或关闭的动画效果,例如打开一个APP时会先加载放大该APP的动画,接着便是APP启动界面的放大动画直至填满整个屏幕。可以观看下述的Redmi K30Pro设备打开和关闭APP的动画效果:
在这里插入图片描述

那么在这个放大或缩小APP图标的动画中,使用drawable下的图片作为APP图标,那么整个放大或缩小的动画都只会使用这一张图片,例如一张低分辨率的图片的放大动画效果则会失真,而高分辨率的缩小动画效果会耗费CPU效率来缩放图片;如果使用mipmap下的图片,Android系统则会根据动画对图片的缩放程度,来自动选择最接近当前分辨率的图片来做缩放处理,这样就实现了Google官方文档中描述的更好视觉效果和更高效率的目的。

2.5 位图错放密度限定符文件夹的后果

如果有一张1MB大小、3500px*2500px的image.jpg图片,那么它在APP中加载会占用多少内存呢?是不是也是占用1MB的内存?

首先我们要知道默认情况下,一个像素占用4个字节,因为Android默认采用ARGB来表示颜色,例如#FFFF7A25表示完全不透明的橙色。接着我们来看看计算APP中加载图片所占用内存的公式:

APP中加载图片所占用内存=横向像素数*纵向像素数*每个像素占用的内存(默认为4)

因此一张1MB大小、3500px*2500px的image.jpg图片,它在APP中所占用内存为3500*2500*4/1024/1024≈33.3786MB,这么一张大分辨率的图片足以让APP抛出一个OOM内存溢出的异常。

那么为什么一张实际占用空间大小为1MB的图片在APP中加载图片所占用内存为33.3786MB呢,这主要是因为该图片是应用了相应压缩算法的jpg图片,而在Android中使用Bitmap时需要该图片的原始数据,所以要按照上述的公式进行计算。

如果把该图片仅存放于drawable-mdpi文件夹下,而屏幕密度对应为xhdpi的设备在APP中加载该图片会占用约133.5144MB的内存,是原来理论值33.3786MB的四倍,这就更容易导致内存溢出了。这主要是因为Android系统会把drawable-mdpi文件夹下的该图片的宽和高各自扩大2倍,以保证该图片能在屏幕密度对应为xhdpi的设备上正常显示。

再举另一个例子,如果把该图片仅存放且正确地存放于drawable-hxdpi文件夹下,而屏幕密度对应为mdpi的设备在APP中加载该图片会占用约8.3447MB的内存,是原来理论值33.3786MB的四分之一。但是Google仍然不推荐我们只存放xhdpi分辨率下的该图片,而是应该提供mdpi和hdpi分辨率下备用位图,这样屏幕密度对应为mdpi的设备就能直接加载drawable-mdpi文件夹下的该图片,就不用再从drawable-xhdpi文件夹中取出该图片再进行缩小了,因为这个缩小过程也是会消耗系统资源的,这也是为什么Google要求我们为mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi屏幕密度设备提供备用位图的原因。

具体的比例关系如下图所示(NX表示表示宽和高是mdpi的N倍,总内存就是N*N倍):

这也是为什么Android要求备用位图要放在对应密度限定符的文件夹中,而位图错放密度限定符的文件夹可能导致OOM内存溢出、消耗不必要的系统资源等问题。

那么在将仅存在于drawable-xhdpi文件夹下的某图片缩小到适配mdpi屏幕分辨率设备的过程中,一定要将此图片完整地加载进入进内存再进行缩小的过程吗?

当然不是,可以使用BitmapFactory.decode()传入一个Options对象,进行某些设置即可读取到该图片的宽高和类型,而不需要读取整个图片到内存中。读取了图片的宽高属性后,可以按照想要的比例进行缩放读取。我的理解是如果你设置的压缩比是2(横向纵向像素各缩小2倍,总压缩比4倍),在BitmapFactory进行decode的时候知道了你的压缩比,它会选择性的读取某些像素点(具体算法未知,可以简单的想成比如原图是100px*100px,现在我们获得到了它的输入流,只是平均地从输入流中读取50px*50px的像素)。这样就实现了大图片不加载到内存先压缩的过程。

这种做法可以用在本地图片的显示处理,同时也可以用在加载网络图片的时候。都是为了避免OOM,同时实现对大图片进行压缩。


本文参考文献:

维基百科-Mipmap

在 Android Studio 中图片资源应该放置在哪里? - BravianZhao的回答 - 知乎

Stack Overflow-Mipmap drawables for icons-sergej shafarenka的回答

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android中drawable或mipmap文件夹存放图片的区别(详细解释) 的相关文章

随机推荐

  • 不直播不露脸也能做短视频变现,想挣点生活费试试这些玩法

    大家好 xff0c 我是 64 我赢助手短视频运营 xff0c 最近一直有小伙伴问我 xff0c 做了好久的短视频一直不赚钱 xff0c 今天总结了一下 xff0c 做了90天短视频还没赚了试试这5种易变现的玩法 新手不直播不露脸也能做短视
  • 科普一下:拍抖音需要什么设备,可能用到的设备合集

    大家好 xff0c 我是 64 我赢助手短视频运营 xff0c 抖音是现在最火的短视频平台之一 xff0c 几乎每个人都在用它 xff0c 抖音视频的发展离不开手机 但你知道吗 xff1f 手机拍摄有很多方面的限制 xff0c 比如手持稳定
  • 短视频上热门技巧总结,这样做你也可以快速上热门。

    最近开始做短视频 xff0c 找了很多短视频运营创作技巧 xff0c 但能上热门的只有那么几个 xff0c 经过近一周的分析 xff0c 结合了我赢上短视频运营创作技巧 xff0c 得到了以下几个经典技巧合集 xff1a 学会一个就值了 首
  • 不要再被骗了,解密短视频里追剧看电影都能赚钱的坑。

    不要再被骗了 解密短视频里追剧看电影都能赚钱的坑 最近刷短视频刷到了好多抖音追剧看电影每天收几百 xff0c 还有截图 xff0c 还有怎么实操的视频 关键不是刷到一个两个 xff0c 是几十个还有越来越多的趋势 都说新入门实操 xff0c
  • 视频号的视频怎么下载到手机?不录屏也不找手机缓存,一键下载。

    你有没有看到有用的视频 xff0c 只收藏起来 xff0c 最后又找不到的时候 前天给朋友找了一个过年快速整理家具杂物的教程 xff0c 谁知道原作者第二天把视频给删掉了 xff0c 朋友说没有来得及看 昨天发给了朋友一个最新的教程 xff
  • 2023年做好自媒体的五个步骤,一步一个脚印稳妥找到结果。

    2023年做好自媒体的五个步骤 一步一个脚印稳妥找到结果 我不管你现在什么负债 破产 xff0c 还是迷茫焦虑 xff0c 通通别管了 xff0c 听话照做执行 看完我这篇内容 xff0c 2023年你还做不起来 xff0c 你就别打嘴炮
  • 2023视频号视频怎么下载到手机?最新验证过的可用方法汇总

    视频号视频怎么下载到手机 xff1f 今天又想下载一个视频号的视频 xff0c 找到收藏已久的视频号视频下载方法 xff0c 结果发现很多方法已经不能用 xff0c 一些能用的也开始收费了 只好重新寻找适合2023最新的几种方法解决视频号下
  • Android系统签名制作

    系统环境 Ubuntu18 04 首先要有对应系统的源码 源码目录build target product security将platform pk8和platform x509 pem copy出来放到一个目录下生成shared priv
  • 使用Cropper进行图片剪裁上传

    在项目中 xff0c 需要多上传的图片按照比例和尺寸进行裁剪 xff0c 这类场景在一些CMS系统中是比较常见的 xff0c 尤其是大部分的文章现在要适配PC Mobile两种平台 xff0c 文章的封面图等便需要按照尺寸做裁剪 xff0c
  • Element-UI消息提示组件Message在Vuex中的调用实现

    在最近的项目开发中 xff0c 前端部分使用 Vue 开发 xff0c 整个页面基于 Element UI 实现 由于是单页面多组件应用 xff0c 使用了 Vuex 做状态管理 为了页面交互的友好和风格的统一 xff0c 消息提醒使用 E
  • Fork原项目新增分支的同步和推送

    在 Github 或者 Gitlab Fork 项目以后 xff0c 原项目增加了新的分支 xff0c 我们可以通过以下流程将分支同步下来 本项目前提假设我们设置了 remote 的名称为 up 与源项目关联 git remote v or
  • Elasticsearch文档版本冲突原理与解决

    一般我们在更新文档时 xff0c 主要的操作流程时 xff1a 读取文档 gt 修改 gt 提交保存 数据中心等保存的都是最新一次提交的内容 大部分时候 xff0c 这都没有什么问题 但是如果两个或更多的请求同时修改一个文档时 xff0c
  • 随笔

    沟通 跨部门沟通 xff0c 首先应确立沟通的目的是双方的有效配合和问题解决的方向 方法 xff0c 去除程序员们自带的问题责任论 xff0c 不能按照 不是我的问题 xff0c 我这OK xff0c 跟我无关 这样的思路去讨论和解决问题
  • Linux内存消耗

    原文 xff1a https web archive org web 20120520221529 http emilics com blog article mconsumption html 本文主要描述如何通过一个合理的方法来测量li
  • ubuntu22 允许root权限远程登录设置

    在 etc ssh sshd config文件中设置 注释 PermitRootLogin prohibit password 添加PermitRootLogin yes
  • 2021年完美解决Gradle下载慢的问题(Android Studio)

    1 问题背景 安卓开发过程中 xff0c 经常会遇到Gradle Wrapper包下载缓慢导致项目无法编译影响开发效率问题 xff0c 极端情况下下载速度只有10kb xff0c 下载一个特定版本的Gradle需要半个小时以上 xff0c
  • 2021年最新版Git一天入门教程

    0 文章背景 Git在其版本2 23后又引入了git switch和git rerstore xff0c 同时Git命令的使用在实际工作过程中不可缺少 xff0c 因此博主本人自己花了一天时间从头复习并深入了Git的使用过程并撰写了这篇文章
  • Git问题解决方案:不建议在没有为偏离分支指定合并策略时执行pull操作(Pulling without specifying how to reconcile divergent branches)

    1 问题背景 如果你也在使用2 27 0及以上版本的Git时 xff0c 使用git pull命令出现以下的警告文案 xff0c 可以通过阅读本篇文章来解决此问题 博主最近在Android Studio上使用git pull命令时 xff0
  • android uinput模拟输入设备事件

    文章目录 嵌入式开发基础使用文件执行注意事项Android 多点触摸协议 xff08 Multi touch Protocol xff09 补充知识 NDK BUILD补充知识 CMake 嵌入式开发基础 使用文件 MainActivity
  • Android中drawable或mipmap文件夹存放图片的区别(详细解释)

    1 问题背景 当在Android Studio来新建一个Android项目 xff0c 该项目有如下的目录结构 xff1a Android项目的某个模块中的res文件夹下 xff0c 有很多以drawable或mipmap开头的子文件夹 x