【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

手把手教你用Siemens EDA破解工具搞定PADs VX2.7安装与卡死问题

本文详细介绍了如何使用Siemens EDA工具解决PADs VX2.7的安装与卡死问题。从License配置到性能调优,提供全面的解决方案,帮助工程师高效完成电子设计自动化任务。特别针对常见的卡顿现象,给出了输入法兼容性调整、图形性能优化等实用技巧。

k8l9m0n的博客 554

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

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

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

均值回归 高频交易_基于布林带的均值回归交易策略

BOLL指标是美国股市分析家约翰·布林根据统计学中的标准差原理设计出来的一种非常简单实用的技术分析指标。一般而言,股价的运动总是围绕某一价值中枢(如均线、成本线等)在一定的范围内变动,布林线指标正是在上述条件的基础上,引进了“股价通道”的概念,其认为股价通道的宽窄随着股价波动幅度的大小而变化,而且股价通道又具有变异性,它会随着股价的变化而自动调整。由于之前大部分交易策略都是选股或者趋势追踪的择时,...

weixin_42528534的博客 1458

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

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

wsxiaohuai126的专栏 552

用Python实现四叉树(quad tree)

import numpy as np #正方形类 class square: #lx、ly为左上角坐标(x对应行号,y对应列号),rx、ry为右下角坐标 def __init__(self,lx,ly,rx,ry): self.lx=lx self.ly=ly self.rx=rx self.ry=ry #检查该矩阵中是否满足条件 #参数:原矩阵,阈值 #返回值:布尔类型 def check(s

weixin_44164489的博客 5868

从零到一:树莓派OpenWrt squashfs固件扩容背后的文件系统魔法

本文深入解析树莓派OpenWrt系统中squashfs固件的扩容原理与操作。通过理解squashfs与overlayfs的协同机制,掌握分区调整和文件系统扩容技巧,解决存储空间限制问题,提升设备可用性。

hadoop5ranger的博客 1038

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

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

吴延宝 1542

il2cpp分析-gobal-metadata.dat解密

打开ida,把libil2cpp拖到ida中按快捷键Shift+F12等待字符串分析完后,搜索global-metadata.dat。ida中双击sub_57EE7C进入,VS code中也跳转到LoadMetadataFile函数。VSCode打开il2cpp源代码,全局搜索global-metadata.dat。工具:010Editor,IDA 7.5,Jadx,VS Code。判断加密逻辑为根据文件的长度循环读取字节码做亦或加密。双击搜索出来的结果,切记要选il2cpp目录下的。

Android_machong的博客 8024

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

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

2401_89820084的博客 914

Android15 修改触摸点上限为40

把MAX_POINTER_ID从默认的31修改为39,这里为什么要从31修改为39,是因为上面说明用BitSet32极限就只能支持32个点,因为从最小的ID是0,所以要支持40个点ID也要对应改为39.最近有个需求,需要修改Android系统的触摸点数,Android系统默认的点数是16个点,因为现在是大屏项目,有客户需要修改为40个点,好吧,客户最大。6.最后进行编译,开机开启触摸点检测,可以使用开发者模式中的显示触摸点功能,再叫上3个人,用双掌触摸屏幕,发现左上角有显示40个触摸点,修改成功。

tzj1058756809的博客 573

YOLOv26与其他目标检测算法的对比分析

本文对YOLOv26与其他主流目标检测算法进行了全面对比分析。YOLOv26在COCO数据集上达到96.0% mAP@0.5和79.0% mAP@0.5:0.95,显著优于其他YOLO系列算法,同时保持85FPS的推理速度和35MB的轻量级模型。相比两阶段算法(如Faster R-CNN),YOLOv26在速度、模型大小和内存占用方面优势明显;相比Anchor-free算法(如CenterNet),YOLOv26在速度和模型压缩方面更优。其核心创新包括动态锚框分配、自注意力机制和轻量级设计,使其成为适用于复

一键难忘的博客 994

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

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

chendedong的博客 1357

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

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

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

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

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

weixin_43277501的博客 5967

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

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

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

weixin_39814482的博客 476

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

安卓开发中经常会遇到因为图片处理不当导致的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、付费专栏及课程。

余额充值