【Android进阶笔记】图片优化(理论大小和实际大小的计算方式)

计算图片所占缓存区的大小 文章目录计算公式具体举例: 在编程中,有时候会遇到从硬件读取图片的问题,此时就需要在内存中为图片分配内存,用于存放读取的图片。 计算公式 为图片分配内存就需要计算图片的大小。 图片所占内存大小 =图片长度(像素) * 图片宽度(像素) * 一个像素所占内存空间(单位:字节) 图像中的像素总数=图片长度(像素) * 图片宽度(像素) 一个像素所占内存空间(单位:字节)=图像深度÷8 ... 阅读详情



1. 图片压缩格式

1.1. 常见的图片格式

格式质量透明压缩方式
png较高支持图片压缩算法。把相似的颜色压缩在一起
jpg/jpeg良好不支持图形压缩算法。把相似的颜色合并在一起,用同一种颜色代替
bmp高不支持24位位图: 每个像素用24位二进制表示,占3个字节256色位图:每个像素用8位二进制表示,占1个字节16色位图: 每个像素有16种颜色选择单色位图: 每个像素有1种颜色选择

1.2. WebP格式

Google在2010年提出。更小的体积下提供肉眼无差别的质量。同时具备了无损和有损的压缩模式、Alpha透明以及动画的特性。在Android 4.0中支持有损的WebP图像,在Android 4.3及更高支持无损和透明的WebP图像。


2. Android内存中的图片

图片的内存大小是指图片完全加载到内存所占用的大小,并非所占用的磁盘大小。

2.1. 位图配置Bitmap.Config

位图配置描述了像素的存储方式,影响质量(颜色深度)、透明度和占用内存的大小。

类型描述组合方式单像素位宽
ALPHA_8无色彩,有透明度A-88位
ARGB_4444质量差。API-29中弃用A-4 R-4 G-4 B-416位
ARGB_8888有色彩,有透明度,提供最佳质量。应尽可能使用它A-8 R-8 G-8 B-832位
HARDWARE特殊配置,当位图仅存储在图形内存中时。API-26中添加
RGBA_F16有色彩,有透明度,适合用于宽域和HDR内容。API-26中添加A-16 R-16 G-16 B-1664位
RGB_565低颜色保真度,无透明度R-5 G-6 B-516位

2.2. 计算占用内存大小

举例:100 × 200 的图片

2.2.1. 理论值

占用内存字节 = 单像素字节 × 图片宽度 × 图片高度

例如:ARGB_8888 配置下占用大小为 4B × 100 × 200 = 80000B = 78.125KB

2.2.2. 实际值

【res目录图片】

系统加载res目录(drawable、mipmap)的资源图片时,先根据存放的不同目录做分辨率转换,再使用转换后的新图宽高运用理论公式计算。

新图高度 = 原图高度 × (设备dpi ÷ 目录dpi)

新图宽度 = 原图宽度 × (设备dpi ÷ 目录dpi)

占用内存字节 = 单像素字节 × 图片宽度 × 图片高度 × (设备dpi ÷ 目录dpi)²

res目录后缀ldpimdpihdpixhdpixxhdpi
dpi值120160240320480

例如:ARGB_8888 配置,设备 dpi = 480,xhdpi 目录下,占用大小为 4B × 100 × 200 × (480 ÷ 320)² = 180000B = 175.78125KB

  • 相同图片,相同 dpi 的设备,不同目录,则图片占用的内存空间大小不一样
  • 相同图片,不同 dpi 的设备,相同目录,则图片占用的内存空间大小不一样

【非res目录图片】

系统加载非 res 目录(磁盘、SD卡、asserts目录、网络下载)的资源图片时,不会做分辨率转换,而是直接使用理论公式计算占用内存大小。

  • 不同的图片加载框架,相同图片可能会占用不同的内存空间大小

3. 图片压缩

减小图片所占用的磁盘/内存空间的大小。

以读取SD卡本地图片并重新保存到SD卡为例。

3.1. 质量压缩

通过改变图片的位深和透明度(即质量)来减小图片占用的磁盘空间大小,不会改变图片的像素,所以不适合作为缩略图,一般用于图片上传。

File sdFile = Environment.getExternalStorageDirectory();
File originFile = new File(sdFile, "originImg.jpg");
// 从本地SD卡读取图片文件,也可以使用BitmapFactory.decode系列方法
Bitmap originBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// 图片格式:Bitmap.CompressFormat 中枚举的3中类型
// 质量:0-100的整数。PNG类型图片因为是无损的,所以此参数无效
originBitmap.compress(【图片格式】, 【质量】, bos);
FileOutputStream fos = null;
try {
    // 压缩后的文件输出流
    fos = new FileOutputStream(new File(sdFile, "resultImg.jpg"));
    fos.write(bos.toByteArray());
} catch (IOException e) {
    e.printStackTrace();
} finally {
    // 两个流执行flush()和close()
}

3.2. 采样率压缩

通过设置 BitmapFactory.Options.inSampleSize,来减小图片的分辨率(即图像的dpi值,非像素值),进而减小图片所占用的磁盘空间和内存大小。

File sdFile = Environment.getExternalStorageDirectory();
File originFile = new File(sdFile, "originImg.jpg");
// 从本地SD卡读取图片文件,也可以使用BitmapFactory.decode系列方法
final BitmapFactory.Options options = new BitmapFactory.Options();
// 设置此参数是仅仅读取图片的宽高到options中,不会将整张图片读到内存中,防止OOM
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(originFile.getAbsolutePath(), options);
final int originWidth = options.outWidth;    // 图片的原始宽度
final int originHeight = options.outHeight;  // 图片的原始高度
options.inJustDecodeBounds = false;
options.inSampleSize = 【缩放值】;  // 缩放值是重点,可以根据图片的原始宽高而定
Bitmap originBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath(), options);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// 图片格式:Bitmap.CompressFormat 中枚举的3中类型
// 质量:0-100的整数。PNG类型图片因为是无损的,所以此参数无效
originBitmap.compress(【图片格式】, 【质量】, bos);
try {
    // 压缩后的文件输出流
    fos = new FileOutputStream(new File(sdFile, "resultImg.jpg"));
    fos.write(bos.toByteArray());
} catch (IOException e) {
    e.printStackTrace();
} finally {
    // 两个流执行flush()和close()
}

缩放值 inSampleSize 会导致压缩的图片的宽高都为原图的 1 / inSampleSize。

  • inSampleSize ≤ 1,则不做缩放。
  • inSampleSize 只能为2的幂,否则会减小为最接近的2的幂。

3.3. 尺寸压缩

通过减少图片的像素来降低图片的磁盘空间大小和内存大小,一般用于生成缩略图。

File sdFile = Environment.getExternalStorageDirectory();
File originFile = new File(sdFile, "originImg.jpg");
// 从本地SD卡读取图片文件,也可以使用BitmapFactory.decode系列方法
Bitmap originBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath());
int radio = 8;  // 缩放比,宽高像素值变为原来的 1/radio
final int resultWidth = originBitmap.getWidth() / radio;
final int resultHeight = originBitmap.getHeight() / radio;
// 创建输出图片,可以改变位图配置以进一步降低占用空间
Bitmap resultBitmap = Bitmap.createBitmap(resultWidth, resultHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(resultBitmap);
RectF rectF = new RectF(0, 0, resultWidth, resultHeight);
//将原图画在缩放之后的矩形上
canvas.drawBitmap(originBitmap, null, rectF, null);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// 图片格式:Bitmap.CompressFormat 中枚举的3中类型
// 质量:0-100的整数。PNG类型图片因为是无损的,所以此参数无效
originBitmap.compress(【图片格式】, 【质量】, bos);
FileOutputStream fos = null;
try {
    // 压缩后的文件输出流
    fos = new FileOutputStream(new File(sdFile, "resultImg.jpg"));
    fos.write(bos.toByteArray());
} catch (IOException e) {
    e.printStackTrace();
} finally {
    // 两个流执行flush()和close()
}

3.4. 图片压缩总结

  • WebP 格式可以在保持清晰度的情况下减小图片的磁盘大小,是一种比较优秀的,Google 推荐。
  • 质量压缩可以减小图片占用的磁盘空间,不会减小在内存中的大小。
  • 采样率压缩通过改变分辨率来减小图片所占用的磁盘空间和内存空间大小,但是采样率只能设置为 2 的幂,可能图片的最优比例在中间。
  • 尺寸压缩也通过改变分辨率来减小图片所占用的磁盘空间和内存空间大小,缩放的尺寸没有什么限制。
  • jni 调用 jpeg 库来弥补安卓系统 skia 框架的不足,也是比较优秀的解决方式。
  • 实际问题中,往往多种方式混合使用以达到最佳效果。

3.5. 实际效果对比

【原图】272k,1024*797。

img

【尺寸压缩】64k,256*200。图片细节较锐利。

img

【采样率压缩】52k,256*200。图片细节较模糊。

img
Android中一张图片占据的内存大小是如何计算(1) 一张图片占用的内存大小的计算公式:分辨率 * 像素点大小;但分辨率不一定是原图的分辨率,需要结合一些场景来讨论,像素点大小就几种情况:ARGB_8888(4B)、RGB_565(2B) 等等。如果不对图片进行优化处理,如压缩、裁剪之类的操作,那么 Android 系统会根据图片的不同来源决定是否需要对原图的分辨率进行转换后再加载进内存。 阅读详情

相关推荐

字节跳动面试官:一张图片占据的内存大小是如何计算

最近封装了个高斯模糊组件,正好将图片相关的理论基础也梳理了下,所以,这次就来讲讲,在 Android 中,怎么计算一张图片在内存中占据的大小,如果要优化,可以从哪些方向着手。 提问 阅读本篇之前,先来想一些问题: Q1:一张 png 格式的图片,图片文件大小为 55.8KB,那么它加载进内存时所占的大小是多少? Q2:为什么有时候,同一个 app,app 内的同个界面,界面上同张图片,但在不同设备上所耗内存却不一样? Q3:同一张图片,在界面上显示的控件大小不同时,它的内存大小也会跟随着改变吗? Q4:图片

weixin_43901866的博客 2278

图片压缩(7)

如何知道一张图片占用内存的大小呢? bitmap的大小= 图片长度 x 图片宽度 x 一个像素点占用的字节数 质量压缩:通过算法用什么来代替一个像素, 不影响 bitmap的大小那么,图片的长,宽,像素都不变,那么bitmap所占内存大小是不会变的 图片的大小计算 2、Bitmap.Config.ARGB_4444 表示一个像素占用2个字节,alpha(A)值,Red(R)值,Green(G)值,Blue(B)值各占4个bites共16bites,即2个字节 数据存储是以“字......

xueyoubangbang的博客 492

Android中一张图片占据的内存大小是如何计算(1),Android彻底组件化方案实践方法

一张图片占用的内存大小的计算公式:分辨率 * 像素点大小;但分辨率不一定是原图的分辨率,需要结合一些场景来讨论,像素点大小就几种情况:ARGB_8888(4B)、RGB_565(2B) 等等。如果不对图片进行优化处理,如压缩、裁剪之类的操作,那么 Android 系统会根据图片的不同来源决定是否需要对原图的分辨率进行转换后再加载进内存。

2401_84148974的博客 912

Android图片压缩尺寸和质量

Android在处理图片时,如果不进行压缩处理,很容易就出现OOM内存溢出(OutOfMemory)问题,所以无论是第三方图片加载还是自己在处理图片时,都要进行压缩处理。Android系统中,一张图片所占用的内存大小与图片尺寸(像素点)和色彩格式(质量)有关,所以Android图片压缩分为尺寸压缩和质量压缩: 尺寸压缩:一张1920*1080的图片尺寸压缩一半后,即960*540,尺寸和像素点是未压

蓝色的天空的博客 1988

Android中一张图片占据的内存大小是如何计算,2024字节跳动春招技术面试题

理清这点蛮重要的,因为碰到过有人说,我一张图片就几 KB,虽然界面上显示了上百张,但为什么内存占用却这么高?所以,我们需要搞清楚一个概念:我们在电脑上看到的 png 格式或者 jpg 格式的图片,png(jpg) 只是这张图片的容器,它们是经过相对应的压缩算法将原图每个像素点信息转换用另一种数据格式表示,以此达到压缩目的,减少图片文件大小。

2401_84148981的博客 1284

体验灵雀云-创建基于Docker的云服务

今天体验了一下灵雀云,创建了第一个基于Docker的云服务。 1.登录灵雀云 2.开始使用 登录之后,从"控制台"进入操作界面,开始创建服务。 首先需要选择一个镜像。灵雀云已经为您提供了一些常用的镜像列表。请在“常用镜像”列表中,选择“其它”,然后找到“alauda/hello-world”镜像,点击它右侧的“选择”按钮,进入服务参数配置页面。 选择完要创建的

tomcat的专栏 3234

Android加载大位图之压缩图片像素和质量参数

android中的大图片一般都要经过压缩才显示,不然容易发生oom,一般我们压缩的时候都只关注其尺寸方面的大小,其实除了尺寸之外,影响一个图片占用空间的还有其色彩细节。

有时候选择比努力更重要,但不努力,连选择的机会都没有! 607

一个AI Agent顶十个软件,toB赛道正在大洗牌

一个AI Agent顶十个软件,toB赛道正在大洗牌

ith321的博客 1331

Android处理照片质量、分辨率、旋转角度一些方法

public class ImageUtil { /**       * 创建1280*720分辨率的图片       * @param filePath       * @return       */       public static Bitmap createImage(String filePath) {           Bitmap bitmap = null

wsxiaohuai126的专栏 552

一个响应ping包延迟偏大的问题

前段时间客户反馈一个使用pc上的命令行ping无线设备(WiFi4)时,设备平均响应时间(测试时长2小时,1秒Ping一次)相比其它机型偏慢的问题,并上传上具体的时间的Log.从log中看到,大多数包的响应还是比较快的,只是个别响应时间较长,且响应时间长的包时间几乎都是一样的100多ms.如下是部分响应时间截图. 整个2小时的测试时间里,总是时不时的出这么上102,104ms的响应时间,这直接导致了平均响应时间被拉大.于是本地测试,也发现了类似的延迟.本地测试时,现象略有...

流风回雪的博客 1万+

SAP ERP与金蝶云星空的集成案例(新能源光伏行业)

通过建设PLM、SAP、MES、WMS、SCADA、EAM等多系统集成的工业互联网平台作为数字化工厂的控制中枢,不仅可以实现人员、设备、物料、工艺参数、产品等生产全流程追溯管理,同时也可以根据数据采集进行生产现场的控制调节,最大程度降低能耗水平。销售订单创建下推金蝶采购订单创建修改、销售订单创建下推金蝶销售订单创建修改、销售发货过账下推金蝶采购入库单、销售发货过账下推金蝶销售出库单:在SAP ERP系统创建销售订单、销售发货过账单后推送到云星空系统,进行采购/销售订单的创建修改、完成物料的入库和出库流程。

集信通 1617

Android中如何计算图片占用的实际内存大小?

当我们看完本篇文章,你应该可以知道: 占用的内存,不是说的图片的文件大小 我们可以在运行时去获取 要掌握图片内存大小的计算方法 一、如何在运行时获取Bitmap的大小? 获取图片实际需要的内存大小 public final int getByteCount() { if(mRecycled) { return 0; } return getRowBytes() * getHeight(); } 图片实际占用的内存大小 因为存在一个复用的场景,比如.

吴延宝 1542

SIwave:在 SIwave 中释放计算频率扫描的强大功能

AEDT 的电路工具允许注入正确的电压和电流。要使用电路工具,SIwave 必须首先使用 PI 求解器求解结构的 S 参数。

jkh920184196的博客 1476

Android中一张图片占据的内存大小是如何计算

一张图片占用的内存大小的计算公式:分辨率 * 像素点大小;但分辨率不一定是原图的分辨率,需要结合一些场景来讨论,像素点大小就几种情况:ARGB_8888(4B)、RGB_565(2B) 等等。如果不对图片进行优化处理,如压缩、裁剪之类的操作,那么 Android 系统会根据图片的不同来源决定是否需要对原图的分辨率进行转换后再加载进内存。

2401_89820084的博客 914

【规则引擎连载3】 WebSphere ILOG JRules 开发——新建一个规则项目

规则项目依赖于bom,bom来自于一个Java项目,所以在建规则项目之前,需要先建立一个Java项目,也就是建模。 说明:原则上是一个规则项目,一个bom。如果规则项目很多,并且每个规则项目的bom都是一样的,那么可以将bom提取出来,单独作为一个项目,这样减少不必要的重复操作,减少维护成本,降低出错几率。这里逐步讲解两种方法来创建规则项目,推荐第二种。 本文主要建立两种规则项目与bom之间的关系,编写相关的规则内容,如操作规则、规则流、决策表等,在后续文章中详细讲解 。

manman的分享 2331

RK3576 USB3.0 DWC3控制器调试:PHY初始化失败排查指南

DWC3 是 Synopsys 公司推出的 USB3.0/3.1 控制器 IP,支持双角色(DRD)模式,可配置为 Host、Device 或 OTG。

小灰灰的博客 1180

安卓性能优化之apk大小优化

AndResGuard 是一款由微信团队开发的 Android 资源保护工具,主要用于混淆资源文件、破坏资源文件可读性以及缩小 APK 大小,其原理与 Java Proguard 类似。能帮助开发者深入了解 APK 文件的内部结构、资源使用、代码构成等信息,进而优化应用性能、减小安装包体积。目录下的子目录(用于进一步组织和管理原始资源文件)等,这取决于应用的具体功能和所使用的技术框架。对于不想被压缩的资源,可以使用keep进行保留,在xml目录下创建keep.xml。文件(包含应用的构建信息)、

chendedong的博客 1357

宇树科技嵌入式面试题及参考答案(春晚机器人的公司)

内存对齐是指在内存中为数据对象分配存储空间时,按照一定的规则将数据存储在特定的地址上,以提高内存访问效率。不同的数据类型在内存中都有其特定的对齐要求,例如,int类型通常要求 4 字节对齐,double类型通常要求 8 字节对齐。这意味着数据的存储地址必须是其对齐字节数的整数倍。如果不进行内存对齐,处理器在访问数据时可能需要进行多次内存访问,从而降低了访问效率。指令可以用于控制结构体内存布局,它允许程序员指定结构体成员的对齐方式。其基本用法是在结构体定义之前使用来指定对齐字节数n,其中n。

大模型大数据攻城狮的专栏 3226

Android | 如何计算图片占用内存的大小

前言 对于一张图片,你知道应该存放在那个资源目录下面吗,或者说,放在那个资源目录下加载起来更省内存呢?在日常开发中我们可能不太注意这些东西,但是这些却是基础,是必不可少的一环,所以这几天重新温习了一下并整理了一下。 基础知识 MDPI HDPI XHDPI XXHDPI XXXHDPI density(像素密度) 160 240 320 480 640 分辨率 360x640 540x960 720x1280 1080x1920 1440x2560 比例 1 1.5 2 3 4

345丶 5410

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

深度解析——图片加载到内存中的大小计算&内存优化

本篇文章已授权微信公众号 hongyangAndroid (鸿洋)独家发布 最近封装了个高斯模糊组件,正好将图片相关的理论基础也梳理了下,所以,这次就来讲讲,在 Android 中,怎么计算一张图片在内存中占据的大小,如果要优化,可以从哪些方向着手。 提问 阅读本篇之前,先来想一些问题: Q1:一张 png 格式的图片,图片文件大小为 55.8KB,那么它加载进内存时所占的大小是多少? Q2:为什么有时候,同一个 app,app 内的同个界面,界面上同张图片,但在不同设备上所耗内存却不一样? Q3:图..

weixin_43277501的博客 5967

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

android计算图片的大小,Android 中一张图片占据的内存大小是如何计算

Android 中一张图片占据的内存大小是如何计算最近封装了个高斯模糊组件 https://www.jianshu.com/p/6064a14d86a3 , 正好将图片相关的理论基础也梳理了下, 所以, 这次就来讲讲, 在 Android 中, 怎么计算一张图片在内存中占据的大小, 如果要优化, 可以从哪些方向着手.提问阅读本篇之前, 先来想一些问题:Q1: 一张 PNG 格式的图片, 图片文件大...

weixin_39814482的博客 476

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

安卓图片内存优化(一)——图片占用内存大小的计算

安卓开发中经常会遇到因为图片处理不当导致的oom问题,因为系统分配给每个应用的最大内存空间是有限的,正常只有几十上百兆(排除通过特殊情况获取到几百兆内存空间的情况)。所以为了节省更多的空间需要对图片进行内存优化。对于很多初学者来说应该都会有这样的疑惑: 只是加载了一张几百k的图片而已,为什么也会导致oom的问题?想知道问题的答案我们得弄明白图片在内存中占用的空间大小是如何计算的。1. 图片相关的

hyhdcl的专栏 2041

Android内存优化之图片优化

关于图片优化,大概如下 为什么要进行图片优化 相信大概刚开始学习Android的时候有过图片过大而直接报错的情况,下面简单介绍一下OOM问题,Android支持的图片格式及图片优化的几种方式 什么是OOM?:Android系统的进程(APP级别)有最大的内存限制,超过这个限制系统就会抛出)OOM错误 图片OOM问题产生的几种情况 1.一个页面一次加载过多的图片 2.加载大图片没有进行压缩 3....

计蒙不吃鱼的博客 1万+
上一篇: 【Android进阶笔记】内存优化(内存泄漏优化)
下一篇: 【Android进阶笔记】进程保活
pren2016
博客等级 码龄16年 6粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值