性能优化:Android中Bitmap内存大小优化的几种常见方式

Android App 性能优化之图片优化 接下来说明一下关于其他内存问题。图片问题,作为一个优秀的Android开发者,在图片的类型选择,图片显示前的处理都是要好好考虑的,因为不同类型图片在Android中的显示代价是不同的,使用不同显示方式代价也是不同的,首先看一下图片类型png与jpg两种类型显示代价有不同,原因在于png占的内存较多,但解码叫简单,若png图片过多,会容易垃圾回收,甚至内存溢出,而jpg的内存小,但解码复杂,会花更多 阅读详情

作者:tinyvampirepudge

Android中的bitmap是比较占用内存的,bitmap的大小直接影响到了应用占用内存的大小。bitmap占用内存大小的计算方式为:

bitmap内存大小 = bitmap宽度(px) * bitmap长度(px) * 一个像素点占用的字节数

BitmapFactory给我们提供了多个decode方法,我们可以从不同的数据源中加载bitmap,如下图所示:

一个像素点占用的字节数对应的参数是Bitmap.Config,它是一个枚举类,具体取值如下:

而每个新建的Bitmap的默认Config的值就Bitmap.Config.ARGB_8888,它表示一个像素点占用4个字节((8 + 8 + 8 + 8) / 8 = 4byte)。

改变Bitmap内存大小

根据上面的原理,我们可以从两个方面减少Bitmap的内存占用,一个是改变Bitmap的宽高,另一个是改变Bitmap.Config的值,将Bitmap.Config.ARGB_8888改为占用字节更少的Bitmap.Config.ARGB_4444或者Bitmap.Config.RGB_565。

具体有以下几种方法:

1、采样率压缩(改变Bitmap大小)。

2、通过martix进行压缩(改变Bitmap大小)。Bitmap.createBitmap或者Bitmap.createScaledBitmap方法。

3、更改Bitmap.Config格式。

具体示例如下: 我们先来看下原图大小:

原图大小为640px * 360px,且是放置在assets目录下的,表示系统不会有缩放操作;如果是放在对应的drawable目录下,则会由系统进行相应的缩放操作。

1、采样率压缩(改变Bitmap大小)。
val assetFileDescriptor = assets.openFd("maomi.jpg")
val fileInputStream = assetFileDescriptor.createInputStream()
val bmpInSampleSizeJpg = BitmapOptionsUtil.decodeSampledBitmapFromFileStream(
    fileInputStream,
    ScreenUtils.dip2px(this, 80f),
    ScreenUtils.dip2px(this, 45f)
)
val descBmpConfigJpg =
    "height:${bmpInSampleSizeJpg?.height},\nwidth:${bmpInSampleSizeJpg?.width},\nallocationByteCount:${bmpInSampleSizeJpg?.allocationByteCount}byte,\n" +
            "byteCount:${bmpInSampleSizeJpg?.byteCount}byte,\nrowBytes:${bmpInSampleSizeJpg?.rowBytes}byte,\ndensity:${bmpInSampleSizeJpg?.density}"
tvInSampleSizeJpgInfo.text = "Jpg通过inSampleSize压缩后的信息:$descBmpConfigJpg"
ivInSampleSizeJpg.setImageBitmap(bmpInSampleSizeJpg)

可以明显的看到,图片的宽高各自缩小为原来的1/4,bitmap占用内存大小为原来的1/16。

采样率压缩Bitmap大小的方式,适用于与原有的图片对象宽高比较大,而目标Bitmap的尺寸比较小,此时就没有必要将Bitmap按照原有的大尺寸加载进来,可以有效的避免内存浪费和OOM。具体采样率(inSampleSize)的计算,请看BitmapOptionsUtil。

2、通过martix进行压缩(改变Bitmap大小)。
val matrix = Matrix()
matrix.setScale(0.1f, 0.1f)
val bmpMatrixJpg = Bitmap.createBitmap(
    bmpOriginJpg, 0, 0, bmpOriginJpg.getWidth(),
    bmpOriginJpg.getHeight(), matrix, true
)
// Bitmap.createScaledBitmap内部也会使用Matrix进行缩放
//            val bmpMatrixJpg = Bitmap.createScaledBitmap(
//                bmpOriginJpg,
//                ScreenUtils.dip2px(this, 60f),
//                ScreenUtils.dip2px(this, 45f),
//                true
//            )
val descBmpConfigJpg =
    "height:${bmpMatrixJpg?.height},\nwidth:${bmpMatrixJpg?.width},\nallocationByteCount:${bmpMatrixJpg?.allocationByteCount}byte,\n" +
            "byteCount:${bmpMatrixJpg?.byteCount}byte,\nrowBytes:${bmpMatrixJpg?.rowBytes}byte,\ndensity:${bmpMatrixJpg?.density}"
tvMatrixJpgInfo.text = "Jpg通过Matrix压缩后的信息:$descBmpConfigJpg"
ivMatrixJpg.setImageBitmap(bmpMatrixJpg)

由于我们设置的缩放比是0.1f,也就是宽高均是之前的1/10,所以压缩后的bitmap占用的内存大小变为原来的1/100。

这种情况适用原图大小和目标bitmap大小均已知的情况。

3、更改Bitmap.Config格式。
val option = BitmapFactory.Options()
option.inPreferredConfig = Bitmap.Config.ARGB_4444
//  option.inPreferredConfig = Bitmap.Config.RGB_565 // 对透明度没要求的话可以试一下rgb_565
val bmpBmpConfigJpg = BitmapFactory.decodeStream(assets.open("maomi.jpg"), null, option)
val descBmpConfigJpg =
    "height:${bmpBmpConfigJpg?.height},\nwidth:${bmpBmpConfigJpg?.width},\nallocationByteCount:${bmpBmpConfigJpg?.allocationByteCount}byte,\n" +
            "byteCount:${bmpBmpConfigJpg?.byteCount}byte,\nrowBytes:${bmpBmpConfigJpg?.rowBytes}byte,\ndensity:${bmpBmpConfigJpg?.density}"
tvBmpConfigJpgInfo.text = "Jpg通过Bitmap.Config压缩后的信息:$descBmpConfigJpg"
ivBmpConfigJpg.setImageBitmap(bmpBmpConfigJpg)

我们将Bitmap.Config的值改为了根据输出的byteCount的值改为了Bitmap.Config.ARGB_4444,根据byteCount输出的值可以明显的看到,bitmap的内存大小减少了一半。

如果对透明度没要求的话可以试一下Bitmap.Config.RGB_565。

这种情况适用于对图片分辨率要求不高的情况。

通过Bitmap#compress方法压缩,质量压缩。

还有一种很重要的压缩方式,通过Bitmap#compress方法,修改quality的值,来改变Bitmap生成的字节流的大小。这种方法不会改变Bitmap占用的内存大小。

质量压缩不会减少图片的像素,它是在保持像素的前提下改变图片的位深及透明度等,来达到压缩图片的目的。图片的长,宽,像素都不变,那么bitmap所占内存大小是不会变的。这里改变的是bitmap对应的字节数组的大小,适合去传递二进制的图片数据,比如微信分享。

val bytearray = getBytesFromCompressBitmap(bmpOriginJpg, 32 * 1024)
val bmpQualityJpg = BitmapFactory.decodeByteArray(bytearray, 0, bytearray.size)
val descQualityJpg =
    "height:${bmpQualityJpg.height},\nwidth:${bmpQualityJpg.width},\nallocationByteCount:${bmpQualityJpg.allocationByteCount}byte,\n" +
            "byteCount:${bmpQualityJpg.byteCount}byte,\nrowBytes:${bmpQualityJpg.rowBytes}byte,\ndensity:${bmpQualityJpg.density},\n" +
            "bytearray:${bytearray.size}"
tvQualityJpgInfo.text = "Jpg进行Quality压缩后的信息:$descQualityJpg"
ivQualityJpg.setImageBitmap(bmpQualityJpg)

/**
 * 将Bitmap的字节流压缩为目标大小
 * @targetSize  单位为Byte
 */
private fun getBytesFromCompressBitmap(
    bitmap: Bitmap,
    targetSize: Int
): ByteArray {
    val baos = ByteArrayOutputStream()
    var quality = 100
    bitmap.compress(Bitmap.CompressFormat.PNG, quality, baos)
    var bytes = baos.toByteArray()
    while (bytes.size > targetSize && quality >= 5) {
        quality -= 5
        if (quality < 0) {
            quality = 0
        }
        // 重置,不然会累加
        baos.reset()
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos)
        bytes = baos.toByteArray()
    }
    try {
        baos.close()
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return bytes
}

可以看到,质量压缩不会改变原有bitmap的大小,它改变的是通过Bitmap#compress方法的字节流。

具体开发过程中,可以根据需要自行选择合适的方式。

Bitmap图像变换实战:缩放、旋转、错切原理与性能优化 在图形图像处理中,位图(Bitmap)作为像素矩阵是存储和处理图像的基础数据结构。其核心操作依赖于变换矩阵(Matrix)的数学原理,通过坐标映射实现图像的几何变换。掌握矩阵变换不仅能实现高质量的缩放、旋转和错切效果,更是优化内存占用和计算性能的关键。在移动应用开发中,合理运用采样缩放(inSampleSize)、滤波插值算法及异步处理,可有效避免OOM并提升用户体验。本文聚焦Android平台,结合Python PIL、OpenCV等跨平台实践,深入解析Bitmap操作中的常见陷阱与优化方案,帮助开发者应 阅读详情

相关推荐

从零到一:Mx_yolo本地训练与K210部署实战指南

本文详细介绍了从零开始进行Mx_yolo本地模型训练到K210部署的全流程实战指南。涵盖环境配置、数据准备、模型训练与调优、模型转换及K210部署等关键步骤,并提供了常见问题解决方案和性能优化技巧,帮助开发者高效完成AI模型在嵌入式设备的落地应用。

weixin_29081163的博客 252

android加载大量图片内存优化,Android图片加载内存优化

利用BitmapFactory.Options实现图片内存优化通过设置options.inPreferredConfig控制内存占用首先准备了一张1280x800的blue_bg.png图片,我们知道这张图片加载到内存默认占用的大小是1280x800x4 = 4096000byteBitmap bitmap = BitmapFactory.decodeResource(getResources()...

weixin_29799175的博客 861

SAP 深入理解库存

当 某个期间发生货物移动的时候,系统在更新mard数据的之前(这个表是实时更新的),会检查此笔业务过账期间和mard里对应记录的期间是否一致,也就是 看这是不是本期间第一笔移动。其二,我们不能保证这定期的作业的确定性,硬件维护、系统性能都可能使这预定的“时刻”出现偏差,如果某一次没能抓取该时刻的库存,对整个报表来说,是数据的缺失;中,当某一期间(Period)的第一项操作更新了物料数量或价值,则SAP系统会向表MBEWH写入一条记录,以第一项操作之前的余额、价格控制为标准。这对于业务数据量大的。

matinal 當冬夜漸暖 。公众号:matinal 3624

android 性能优化-图片

bitmap内存大小 = (图片长度 x 图片宽度)(分辨率压缩) x 单位像素占用的字节数 (改变编码格式); 分辨率压缩 为什么要比较实际宽高和目标宽高比呢? 改变编码格式: ...

emmmsuperdan的博客 3905

RAG——从0到1快速搭建RAG应用

本文介绍了基于LangChain框架构建RAG(检索增强生成)应用的技术方案,涵盖核心模块选型与实现流程。技术栈包括:LangChain应用框架、pypdf文档解析、RecursiveCharacterTextSplitter文本分块、bge-small-zh-v1.5向量模型、Faiss向量库和通义千问大模型。文章详细说明了开发环境配置步骤,包括虚拟环境创建、依赖库安装和模型下载。核心代码分为索引、检索、生成三大流程,索引流程完成PDF文档解析、分块和向量化存储;检索流程实现查询向量化和相似度匹配;生成流

小志的博客 596

STM32 RT-Thread 系统分析(1)- 启动文件

RT-Thread STM32 系统分析(1)- 启动文件前言基本信息前言说明三级目录 前言 基本信息 名称 描述说明 RT-Thread Studio 软件版本 版本: 1.1.3 RT-Thread 系统版本 4.0.2 STM32CubeIDE 软件版本 1.4.0 STM32芯片型号 STM32F013VG 前言说明 使用了STM32CubeIDE 和 RT-Thread Studio 建立了相同型号芯片的工程,对比其中启动文件内容差异如下: 左侧是RT-Threa

鸳鸯冰笔的博客 4099

Android:调整Bitmap的大小

/** * 调整图片大小 * * @param bitmap 源 * @param dst_w 输出宽度 * @param dst_h 输出高度 * @return */ public static Bitmap imageScale(Bitmap bitmap, int dst_w, int dst_h) { int src_w = bitmap.getWidth(); int sr...

baidu_24743861的博客 1496

手把手教你用STM32F303和LAN9252搭建EtherCAT从站(附IO/AD/DA完整代码)

本文详细介绍了如何使用STM32F303和LAN9252搭建EtherCAT从站,涵盖硬件选型、开发环境配置、协议栈移植及IO/AD/DA功能实现。通过实战指南和完整代码,帮助开发者快速掌握工业自动化中的实时通信技术,提升系统性能与可靠性。

weixin_26802933的博客 235

android 按比例设置Bitmap的大小

android 按比例设置Bitmap的大小

weixin_46409629的博客 1394

OpenCASCADE(OCC)读取 STEP 模型文件并在MFC中显示

OpenCASCADE(OCC)读取 STEP 模型文件并在MFC中显示

weixin_61900468的博客 1万+

linux上使用tun/tap设备模拟一个虚拟网卡,并将该虚拟网卡连接到新创建的网桥上

tun/tap设备是操作系统内核中的虚拟网络设备,是用软件模拟的网络设备,提供与硬件网络设备完全相同的功能。主要用于用户空间和内核空间传递报文。tun/tap对于硬件网络设备而言,一端连接的是物理网络,一端连接的是网络协议栈。对于tun/tap设备而言,一端连接的是应用程序(通过 字符设备文件),一端连接的是网络协议栈。

糖果墙的博客 6413

Bitmap: Android 内存刺客 | 开发者说·DTalk

本文原作者: 椎锋陷陈,原文发布于: 星际码仔雪糕刺客是被网友们玩坏了的梗,指的是那些以平平无奇的外表混迹于众多平价雪糕之中的贵价雪糕。由于没有明确标明价格,通常要等到结账的时候才会发现,犹如一个潜藏于普通人群中的刺客般,伺机对那些大意的顾客们的钱包刺上一剑,因此得名。而在 Android 中,也有这么一个内存刺客,其作为我们日常开发中经常接触的对象之一,却常常因为使用方式的不当,时不时地就会给我...

Android开发者 605

量化交易 米筐 因子分组打分(成长因子)

分组动手练习 在米筐上因子数据没有处理,提供的很多因子没有默认分类,存在一些因子没有的情况,我们就选择一些常见的因子。 价值因子 质量因子 成长因子(历史名称) pe_ratio return_on_invested_capital in_revenue pcf_ratio du_return_on_equity inc_eps pb_ratio return_on_asset_net_profit inc_total_asset market_cap return_on_equ

廷益_飞鸟的博客 933

Android 性能优化--内存优化之Bitmap优化

Android开发中,Bitmap是经常会遇到的对象,特别是在列表图片展示、大图显示等界面。而Bitmap实实在在是内存使用的“大客户”。如何更好的使用Bitmap,减少其对App内存的使用,是Android优化方面不可回避的问题。因此,本文从常规的Bitmap使用,到Bitmap内存计算进行了介绍,最后分析了Bitmap的源码和其内存模型在不同版本上的变化。 Bitmap的使用 一般来说,一个对...

Simon_Crystin的博客 1154

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

IEM模型,地表粗糙度模拟

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

android性能优化之图片Bitmap优化(含源码)

android性能优化之图片Bitmap优化

qq_23081779的博客 1230

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Android性能优化(五)之细说Bitmap

在上一篇《Android性能优化(四)之内存优化实战》中谈到那个内存中的大胖子Bitmap,Bitmap对内存的影响极大。 例如:使用Pixel手机拍摄4048x3036像素(1200W)的照片,如果按ARGB_8888来显示的话,需要48MB的内存空间(4048*3036*4 bytes),这么大的内存消耗极易引发OOM。本篇文章就来说一说这个大胖子。 1. Bitmap内存模型 Android Bitmap内存的管理随着系统的版本迭代也有演进: 1.在Android 2.2(API8)之前,当G

Tiger的专栏 691

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

深入探索Android Bitmap:从原理到实战

Bitmap 在 Android 开发中占据着举足轻重的地位,作为图片在内存中的呈现形式,它为开发者提供了强大的图像操作能力。从原理上看,Bitmap 通过像素点集合存储图像信息,其颜色通道和内存占用的计算方式决定了图像的显示效果和内存开销。在实际应用中,我们需要根据不同的需求选择合适的创建和加载方式,并且要注意优化性能,避免内存溢出等问题。通过本文的介绍,我们深入了解了 Bitmap 的内部原理,包括颜色通道的存储方式和内存占用的计算方法。

顾林海 2291

详解Android Bitmap:关于你所要知道的一切

前言 在平时的 Android 开发中,与 Bitmap 打交道可以说是再常见不过的事了。我在写这篇文章之前,对于 Bitmap 相关的一些东西总是模模糊糊,比如 Bitmap 的文件大小还有占用内存大小的区别,还有对 Bitmap 压缩的几种方法各自的区别和通途是什么,等等 在这篇文章中,我将会把在 Bitmap 中相关的知识点都一一介绍,如果你也是对 Bitmap 总是感觉模模糊糊的话, 相信你看完这篇文章后一定会有所收获 目录 一、Bitmap 的创建 二、Bitmap 的颜色配置信息与压缩方

鸿蒙开发知识记录 1026

Android Bitmap 详解:关于 Bitamp 你所要知道的一切

原文链接 https://www.jianshu.com/p/eef3daeeecbc 前言 在平时的 Android 开发中,与 Bitmap 打交道可以说是再常见不过的事了。我在写这篇文章之前,对于 Bitmap 相关的一些东西总是模模糊糊,比如 Bitmap 的文件大小还有占用内存大小的区别,还有对 Bitmap 压缩的几种方法各自的区别和用途是什么,等等 在这篇文章中,我将会把在 Bitmap 中相关的知识点都一一介绍,如果你也是对 Bitmap 总是感觉模模糊糊的话, 相信你看完这篇文章后一定

silencefly的博客 1159

Android性能优化(七)Bitmap内存压缩

一、Bitmap内存占用 内存大小计算 ARGB_8888 ARGB各占8位,即WIDTH*HEIGHT*4 RGB_565 R5位,G6位,B5位,即16位WIDTH*HEIGH*2 getByteCount 返回可用于存储此位图像素的最小字节数。 BitmapFactory.Options 控制解码图片参数 inDensi...

Easyhood的博客 773

android内存分析bitmap,Android性能优化:Bitmap详解&你的Bitmap占多大内存?

在开发app时,显示一张本地图片,这张图片在加载时会占用大多内存呢?猜测占用内存大小和以下几个因素有关:设计师切图,图片本身的分辨率;图片所放文件夹代表的 密度 dpi;手机自身的屏幕密度;经过系统缩放得到的最终加载到手机上图片的密度和占用的内存。我们知道Android中在加载本地大图时,很容易OOM,主要原因在于加载的Bitmap占用内存太大。接下来将围绕以下几个问题说明如何计算一张Bitmap...

weixin_33413018的博客 322

Android Bitmap内存管理与性能优化全解析

在Android应用开发中,内存管理是影响应用性能与稳定性的核心环节。其原理在于Android系统采用Java堆与Native堆的双层内存模型,不同版本对内存分配策略有显著差异。这一机制的技术价值在于,通过精细控制内存使用,可有效避免OOM(内存溢出)崩溃,提升应用流畅度与用户体验。尤其在处理图像资源时,Bitmap作为图形系统的基石,其内存占用直接影响应用性能。应用场景广泛覆盖图片加载、列表展示、大图浏览等常见功能。本文聚焦Bitmap的内存模型、采样率计算与复用机制,结合OOM崩溃分析与inBitmap

weixin_34332905的博客 684

Android 性能优化:内存优化(实践篇)

前一篇文章Android性能优化:内存优化 (思路篇)大概梳理了Android 内存原理和优化的必要性及应该如何优化,输出了一套短期和长期内存优化治理的SOP方案。由于24年的kpi是关于OOM和内存优化治理,结果来看OOM降低了 70%,但是内存优化结果不太理想,线程数有一定控制,但是内存水位依然稳定,流畅看播的业务专项,在技术层面可一定程度遏制内存增高,但是对业务影响正相关性还未验证成功,实验组和对照组数据彼此纠缠。

魔都大白 1892

9102年底将至,BAT高级开发21道汇总:Bitmap+Handler+性能优化篇

前言 面试:如果不准备充分的面试,完全是浪费时间,更是对自己的不负责。 今天给大家分享下我整理的BAT架构面试专题及答案,其中大部分都是大企业面试常问的面试题,可以对照这查漏补缺,当然了,这里所列的肯定不可能覆盖全部方式,不过也希望能对即将找工作的朋友起到一些帮助!在这由于文字很多,我总结了Android面试所涉及到的常问范围及架构面试专题和答案解析和架构视频资料分享给大家 更多完整项目下载...

Android_SE的博客 346
上一篇: 来自Android 高工的感慨~
下一篇: ButterKnife为什么执行效率为什么比其他注入框架高?它的原理是什么
懂你的大海
博客等级 码龄6年 9049粉丝 1381原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值