Bitmap -> Bitmap安卓设备上的显示和内存

embedded/2025/3/6 15:44:34/

Android 屏幕显示与 Bitmap 内存详解

前言

Android 开发中,理解屏幕显示单位和 Bitmap 内存占用是构建高效应用的基础。本文将详细介绍相关概念、计算公式及单位转换,并通过实例分析 Bitmap 在内存中的表现。

一、屏幕显示单位基础

1.1 基本单位及概念

  • px 手机屏幕分辨率的基本单位,与物理像素一一对应
  • dp 密度无关像素,1dp = (屏幕密度/160)px,用于保证不同屏幕密度下视图尺寸的一致性
  • sp 可缩放像素,主要用于字体大小,会随系统字体大小设置变化
  • dpi 屏幕密度,每英寸包含的像素点数,密度越大,每英寸内容纳的点数就越多
  • ppi 每英寸像素数,由屏幕分辨率和物理尺寸计算得出的近似值

1.2 Android 密度等级

密度等级密度值(dpi)比例对应系数资源目录
ldpi1200.75x0.75drawable-ldpi
mdpi1601x1.0drawable-mdpi
hdpi2401.5x1.5drawable-hdpi
xhdpi3202x2.0drawable-xhdpi
xxhdpi4803x3.0drawable-xhdpi
xxxhdpi6404x4.0drawable-xxhdpi

二、屏幕单位计算公式与转换

2.1 基本计算公式

  • pxdp 的转换:
kotlin">px = dp × (dpi ÷ 160)
dp = px × (160 ÷ dpi)
  • pxsp 的转换:
kotlin">px = sp × (dpi ÷ 160) × fontScale
sp = px ÷ ((dpi ÷ 160) × fontScale)
  • ImageView 实际像素计算:
    实际像素宽/高 = XML中设置的dp值 × (inTargetDensity ÷ 160)
  • Bitmap 尺寸计算:
    加载后的Bitmap宽/高 = 原始宽/高 × (inTargetDensity ÷ inDensity)

2.2 单位转换工具

kotlin">object DisplayUtils {/*** dp转px*/fun dp2px(context: Context, dpValue: Float): Int {val scale = context.resources.displayMetrics.densityreturn (dpValue * scale + 0.5f).toInt()}/*** px转dp*/fun px2dp(context: Context, pxValue: Float): Int {val scale = context.resources.displayMetrics.densityreturn (pxValue / scale + 0.5f).toInt()}/*** sp转px*/fun sp2px(context: Context, spValue: Float): Int {val fontScale = context.resources.displayMetrics.scaledDensityreturn (spValue * fontScale + 0.5f).toInt()}/*** px转sp*/fun px2sp(context: Context, pxValue: Float): Int {val fontScale = context.resources.displayMetrics.scaledDensityreturn (pxValue / fontScale + 0.5f).toInt()}/*** 获取屏幕宽度(px)*/fun getScreenWidth(context: Context): Int {return context.resources.displayMetrics.widthPixels}/*** 获取屏幕高度(px)*/fun getScreenHeight(context: Context): Int {return context.resources.displayMetrics.heightPixels}/*** 获取状态栏高度*/fun getStatusBarHeight(context: Context): Int {val resourceId = context.resources.getIdentifier("status_bar_height", "dimen", "android")return if (resourceId > 0) {context.resources.getDimensionPixelSize(resourceId)} else {0}}
}

2.3 获取设备显示信息

kotlin">fun getDisplayMetricsInfo(context: Context): String {val dm = context.resources.displayMetricsreturn """屏幕宽度(px): ${dm.widthPixels}屏幕高度(px): ${dm.heightPixels}屏幕密度(density): ${dm.density}屏幕密度DPI: ${dm.densityDpi}X轴DPI: ${dm.xdpi}Y轴DPI: ${dm.ydpi}字体缩放因子: ${dm.scaledDensity}屏幕宽度(dp): ${dm.widthPixels / dm.density}屏幕高度(dp): ${dm.heightPixels / dm.density}""".trimIndent()
}

三、Bitmap 内存计算与管理

3.1 Bitmap 内存计算公式

Bitmap 在内存中的占用大小计算公式:

kotlin">内存大小(字节) = 宽度(像素) × 高度(像素) × 每像素字节数

每像素字节数由 Bitmap.Config 决定:

配置类型每像素字节数说明
ALPHA_81仅存储透明度
RGB_5652无透明度通道
ARGB_88884默认配置,最高质量
RGBA_F168高精度浮点配置

3.2 Bitmap 内存大小:未压缩的原始像素数据大小

  • 以一张 1920×1080 分辨率的图片为例:
    • 内存占用 (ARGB_8888)1920 × 1080 × 4 = 8,294,400 字节 ≈ 7.91 MB

3.3 不同单位的内存大小表示

kotlin">fun calculateBitmapMemorySize(bitmap: Bitmap): String {val bytes = bitmap.byteCountval kb = bytes / 1024.0val mb = kb / 1024.0return """内存占用(Bytes): $bytes bytes内存占用(KB): ${String.format("%.2f", kb)} KB内存占用(MB): ${String.format("%.2f", mb)} MB""".trimIndent()
}

http://www.ppmy.cn/embedded/170511.html

相关文章

【Azure 架构师学习笔记】- Azure Databricks (15) --Delta Lake 和Data Lake

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (14) – 搭建Medallion Architecture part 2 前言 ADB 除了UC 这个概念之外,前面【Azure 架构师学习笔记】- Azure Databricks (1…

Uniapp使用wxml-to-canvas进行动态页面转图片

参考文章链接:https://www.cnblogs.com/liangtao999/p/16719534.html 官方的链接:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/extended/component-plus/wxml-to-canvas.html 一、引入组件: 1、方法一&#…

洛谷 P11830 省选联考2025 幸运数字 题解

题意 小 X 有 n n n 个正整数二元组 ( a i , b i ) ( 1 ≤ i ≤ n ) (a_i, b_i) (1 \leq i \leq n) (ai​,bi​)(1≤i≤n)。他将会维护初始为空的可重集 S S S,并对其进行 n n n 轮操作。第 i ( 1 ≤ i ≤ n ) i (1 \leq i \leq n) i(1≤i≤n) 轮操作中&#…

SPI硬件设计及通信原理解析

SPI(Serial Peripheral interface,串行外围设备接口),是一种高速的,全双工,同步通信总线。 SPI采用主从控制模式(Master--Slave)架构,一般有1个主设备、一个或多个从设备,使得主设备可以与多个从设备之间实现片间通信。 SPI在芯片管脚中只占用四根线节约了芯片的管脚…

记一次误禁用USB导致键盘鼠标失灵的修复过程

背景说明 在电脑上插入了一个USB hub,然后弹窗提示:“集线器端口上出现电涌”,点开让选择“重置”或者“关闭”,不小心点了关闭,结果这个usb口就被关了,再插任何东西都没反应,找了很多办法都恢…

前端基础之消息订阅与发布

需要下载npm I pubsub-js 在Student.vue中发送数据 <template> <div class"demo"> <h2 class"title">学生姓名:{{name}}</h2> <h2>学生性别:{{sex}}</h2> <button click"sendStudentName">将学生名给…

Android中的Loader机制

Android中的Loader机制是在Android 3.0版本之后引入的一种异步加载数据的方法。以下是对Android中Loader机制的详细解释&#xff1a; 一、Loader机制的基本概念 Loader是Android提供的一种异步加载数据的机制&#xff0c;它可以在后台线程中执行耗时操作&#xff0c;并在加载…

Java面试知识点总结

目录 基础篇 一、JAVA: 二、JDK ?JRE ?JVM的区别&#xff1a; 三、java的基本数据类型 四、switch默认接受的几种数据类型 五、修饰符的作用 六、Static修饰符 七、final,finally,finalize 三者区别 八、StringBuffer StringBuilder String 区别 九、String的常用方…