Bitmap -> Bitmap安卓设备上的显示和内存
Android
屏幕显示与 Bitmap
内存详解
前言
在 Android
开发中,理解屏幕显示单位和 Bitmap
内存占用是构建高效应用的基础。本文将详细介绍相关概念、计算公式及单位转换,并通过实例分析 Bitmap
在内存中的表现。
一、屏幕显示单位基础
1.1 基本单位及概念
px
手机屏幕分辨率的基本单位,与物理像素一一对应dp
密度无关像素,1dp = (屏幕密度/160)px
,用于保证不同屏幕密度下视图尺寸的一致性sp
可缩放像素,主要用于字体大小,会随系统字体大小设置变化dpi
屏幕密度,每英寸包含的像素点数,密度越大,每英寸内容纳的点数就越多ppi
每英寸像素数,由屏幕分辨率和物理尺寸计算得出的近似值
1.2 Android 密度等级
密度等级 | 密度值(dpi) | 比例 | 对应系数 | 资源目录 |
---|---|---|---|---|
ldpi | 120 | 0.75x | 0.75 | drawable-ldpi |
mdpi | 160 | 1x | 1.0 | drawable-mdpi |
hdpi | 240 | 1.5x | 1.5 | drawable-hdpi |
xhdpi | 320 | 2x | 2.0 | drawable-xhdpi |
xxhdpi | 480 | 3x | 3.0 | drawable-xhdpi |
xxxhdpi | 640 | 4x | 4.0 | drawable-xxhdpi |
二、屏幕单位计算公式与转换
2.1 基本计算公式
px
与dp
的转换:
px = dp × (dpi ÷ 160)
dp = px × (160 ÷ dpi)
px
与sp
的转换:
px = sp × (dpi ÷ 160) × fontScale
sp = px ÷ ((dpi ÷ 160) × fontScale)
ImageView
实际像素计算:
实际像素宽/高 =XML
中设置的dp
值 × (inTargetDensity
÷160
)Bitmap
尺寸计算:
加载后的Bitmap
宽/高 = 原始宽/高 × (inTargetDensity
÷inDensity
)
2.2 单位转换工具
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 获取设备显示信息
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
在内存中的占用大小计算公式:
内存大小(字节) = 宽度(像素) × 高度(像素) × 每像素字节数
每像素字节数由 Bitmap.Config
决定:
配置类型 | 每像素字节数 | 说明 |
---|---|---|
ALPHA_8 | 1 | 仅存储透明度 |
RGB_565 | 2 | 无透明度通道 |
ARGB_8888 | 4 | 默认配置,最高质量 |
RGBA_F16 | 8 | 高精度浮点配置 |
3.2 Bitmap
内存大小:未压缩的原始像素数据大小
- 以一张
1920×1080
分辨率的图片为例:- 内存占用
(ARGB_8888)
:1920 × 1080 × 4 = 8,294,400 字节 ≈ 7.91 MB
- 内存占用
3.3 不同单位的内存大小表示
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()
}
相关文章:
Bitmap -> Bitmap安卓设备上的显示和内存
Android 屏幕显示与 Bitmap 内存详解 前言 在 Android 开发中,理解屏幕显示单位和 Bitmap 内存占用是构建高效应用的基础。本文将详细介绍相关概念、计算公式及单位转换,并通过实例分析 Bitmap 在内存中的表现。 一、屏幕显示单位基础 1.1 基本单位及…...

QT study DAY2
作业 代码 Widget.h class Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);~Widget();void save_data(const QString& filename,const QString& data); private slots:void on_lineEdit_textChanged(); //账户栏void on_l…...

QT-自定义参数设计框架软件
QT-自定义参数设计框架软件 Chapter1 QT-自定义参数设计框架软件前言一、演示效果二、使用步骤1.应用进行参数注册2.数据库操作单例对象3.参数操作单例对象 三、下载链接 Chapter2 Qt中管理配置参数(QSettings、单例模式)1 前言2 QSettings类ini文件写in…...

VUE集成Live2d
VUE集成Live2d 目前基于大模型,可以实现一个桌面的3D动画小人,个人猜测可以简介这个项目进行实现 1-参考网址 试了很多项目,只有这个项目直观的把问题说清楚了 Live2D Vue3技术应用:https://blog.csdn.net/hh1233321/article/details/1406947…...
【CPP面经】科大讯飞 腾讯后端开发面经分享
文章目录 C 面试问题整理基础问题简答1. 内存对齐2. this 指针3. 在成员函数中删除 this4. 引用占用内存吗?5. C 越界访问场景6. 进程通信方式7. 无锁队列实现8. ping 在哪一层?实现原理?9. HTTPS 流程10. GDB 使用及 CPU 高使用定位11. 智能…...

el-card 结合 el-descriptions 作为信息展示
记录下el-card 组合 el-descriptions 实现动态展示信息 文章结构 实现效果1. el-descriptions 组件使用1.1 结合v-for实现列表渲染1.2 解析 2. 自定义 el-descriptions 样式2.1 修改背景色、字体颜色2.2 调整字体大小2.3 解析 3. el-card 结合 el-descriptions 作为信息展示3.…...
GaussDB自带诊断工具实战指南
一、引言 GaussDB是一种分布式的关系型数据库。在数据库运维中,快速定位性能瓶颈、诊断故障是保障业务连续性的关键。GaussDB内置了多种诊断工具,结合日志分析、执行计划解析和实时监控功能,帮助开发者与运维人员高效解决问题。本文深入讲解…...

LeetCode 链表章节
简单 21. 合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1,2,3,4,4]示例 2: 输入:l1 [], l2…...

SSL证书和HTTPS:全面解析它们的功能与重要性
每当我们在互联网上输入个人信息、进行在线交易时,背后是否有一个安全的保障?这时,SSL证书和HTTPS便扮演了至关重要的角色。本文将全面分析SSL证书和HTTPS的含义、功能、重要性以及它们在网络安全中的作用。 一、SSL证书的定义与基本概念 S…...

正交投影与内积空间:机器学习的几何基础
前言 本文隶属于专栏《机器学习数学通关指南》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见《机器学习数学通关指南》 正文 🔍 1. 内积空间的…...

Qt中txt文件输出为PDF格式
main.cpp PdfReportGenerator pdfReportGenerator;// 加载中文字体if (QFontDatabase::addApplicationFont(":/new/prefix1/simsun.ttf") -1) {QMessageBox::warning(nullptr, "警告", "无法加载中文字体");}// 解析日志文件QVector<LogEntr…...

《HelloGitHub》第 107 期
兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等,涵盖多种编程语言 Python、…...
Langchain解锁LLM大语言模型的结构化输出能力(多种实现方案)
在 LangChain解锁LLM大语言模型的结构化输出能力:调用 with_structured_output() 方法 这篇博客中,我们了解了格式化LLM输出内容的必要性以及如何通过调用langchain框架中提供的 with_structured_output() 方法对LLM输出进行格式化(三种可选方…...

AI数据分析:deepseek生成SQL
在当今数据驱动的时代,数据分析已成为企业和个人决策的重要工具。随着人工智能技术的快速发展,AI 驱动的数据分析工具正在改变我们处理和分析数据的方式。本文将着重介绍如何使用 DeepSeek 进行自动补全SQL 查询语句。 我们都知道,SQL 查询语…...
力扣-动态规划-115 不同子序列
思路 dp数组定义:0_i-1的字符串中有0_j-1的字符串有dp[i][j]个递推公式: if(s[i-1] t[j-1]){dp[i][j] dp[i-1][j-1] dp[i-1][j]; }else{dp[i][j] dp[i-1][j]; } 在该元素相同时,有两种可能1:使用该元素,所以0_i-2…...

Qt C++ 开发 动态上下页按钮实现
项目开发,想实现动态的显示按钮,考虑使用QStackedWidget做两个页面去切换。 首先,我们使用Qt ui 画出两个QStackedWidget的两个页面 要实现切换,我们只需要调用stackedWidget->setCurrentIndex(index)就行。 那么如何自动调…...

数据结构第五节:排序
1.常见的排序算法 插入排序:直接插入排序、希尔排序 选择排序:直接选择排序、堆排序 交换排序:冒泡排序、快速排序 归并排序:归并排序 排序的接口实现: // 1. 直接插入排序 void InsertSort(int* a, int n); // 2. 希…...

从文件到块: 提高 Hugging Face 存储效率
Hugging Face 在Git LFS 仓库中存储了超过30 PB 的模型、数据集和 Spaces。由于 Git 在文件级别进行存储和版本控制,任何文件的修改都需要重新上传整个文件。这在 Hub 上会产生高昂的成本,因为平均每个 Parquet 和 CSV 文件大小在 200-300 MB 之间&#…...
Android14 串口控制是能wifi adb实现简介
Android14 串口控制是能wifi adb实现简介 一、前言 文章目录 Android14 串口控制是能wifi adb实现简介一、前言二、Android14 串口控制是能wifi adb实现1、设置prop属性命令开启adb(1)相关prop属性设置(2)在设置界面或者 ifconfi…...
vue3中 组合式~测试深入组件:事件 与 $emit()
一、语法(props) 第一步:在组件模板表达式中,可以直接用$emit()方法触发自定义事件, <!-- MyComponent --> <button click"$emit(someEvent)">Click Me</button> 第二步父组件可以通过 v-on (缩写为 ) 来监听…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...

练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...