Android-高效加载大图

Android 高效加载大图

  • 前言
  • 读取位图尺寸和类型
  • 将按比例缩小的版本加载到内存中

前言

图片有各种形状和大小。在很多情况下,它们的大小超过了典型应用界面的要求。例如,系统“图库”应用会显示使用 Android 设备的相机拍摄的照片,这些照片的分辨率通常远高于设备的屏幕密度。

但是手机中每个应用的内存是有限的,程序占用了过高的内存就容易出现OOM(OutOfMemory)异常。理想情况下只希望在内存中加载较低分辨率的版本。分辨率较低的版本应与显示该版本的界面组件的大小相匹配。分辨率更高的图片不会带来任何明显的好处,但仍会占用宝贵的内存,并且会因为额外的动态缩放而产生额外的性能开销。

读取位图尺寸和类型

BitmapFactory类提供了几种用于从各种来源创建 Bitmap 的解码方法(decodeByteArray()decodeFile()decodeResource() 等)。根据图片数据源选择最合适的解码方法。这些方法尝试为构造的位图分配内存,因此很容易导致 OutOfMemory 异常。每种类型的解码方法都有额外的签名,允许你通过 BitmapFactory.Options 类指定解码选项。在解码时inJustDecodeBounds 属性设置为 true 可避免内存分配,为位图对象返回 null,但设置 outWidthoutHeightoutMimeType。此方法可让你在构造位图并为其分配内存之前读取图片数据的尺寸和类型。

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;

在这里插入图片描述

为避免出现 java.lang.OutOfMemory 异常,请先检查位图的尺寸,然后再对其进行解码,除非你绝对信任该来源可为你提供大小可预测的图片数据,以轻松适应可用的内存。

将按比例缩小的版本加载到内存中

既然图片尺寸已知,便可用于确定应将完整图片加载到内存中,还是应改为加载下采样版本。以下是需要考虑的一些因素:

  • 在内存中加载完整图片的估计内存使用量
  • 根据应用的其他内存要求,你愿意分配用于加载此图片的内存量
  • 用于展示这张图片的控件的实际大小
  • 当前设备的屏幕尺寸和分辨率

例如,如果 1024x768 像素的图片最终会在 ImageView 中显示为 128x96 像素缩略图,则不值得将其加载到内存中。

如需让解码器对图片进行下采样,以将较小版本加载到内存中,请在 BitmapFactory.Options 对象中将 inSampleSize 设置为 true。例如,分辨率为 2048x1536 且以 4 作为 inSampleSize 进行解码的图片会生成大约 512x384 的位图。将此图片加载到内存中需使用 0.75MB,而不是完整图片所需的 12MB(假设位图配置为 ARGB_8888)。下面的方法用于计算样本大小值,即基于目标宽度和高度的 2 的幂:

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {// 源图片的高度和宽度final int height = options.outHeight;final int width = options.outWidth;int inSampleSize = 1;if (height > reqHeight || width > reqWidth) {final int halfHeight = height / 2;final int halfWidth = width / 2;// 计算最大的 inSampleSize 值,该值应是 2 的幂次,// 且高度和宽度均大于所要求的高度和宽度。while ((halfHeight / inSampleSize) >= reqHeight&& (halfWidth / inSampleSize) >= reqWidth) {inSampleSize *= 2;}}return inSampleSize;
}

inSampleSize: 如果设置为 > 1 的值,则请求解码器对原始图像进行二次采样,返回较小的图像以节省内存。样本大小是任一维度中与解码位图中的单个像素相对应的像素数。例如,inSampleSize == 4 返回图像的宽度/高度为原始图像的 1/4,像素数为 1/16。任何<= 1的值都被视为与1相同。
注意: 解码器使用基于2的幂的最终值,任何其他值将向下舍入到最接近的2的幂。

如需使用此方法,先将 inJustDecodeBounds 设为 true 进行解码,传递选项,然后使用新的 inSampleSize 值并将 inJustDecodeBounds 设为 false 再次进行解码:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,int reqWidth, int reqHeight) {// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(res, resId, options);// 计算inSampleSizeoptions.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);// 使用计算的inSampleSize值再次解析图片options.inJustDecodeBounds = false;return BitmapFactory.decodeResource(res, resId, options);
}

采用此方法,可以轻松地将任意大尺寸的位图加载到显示 100x100 像素缩略图的 ImageView 中,如以下示例代码所示:

imageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.screen_capture, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
Log.i(TAG, "onCreate: bitmap == null ? " + (null == bitmap));
Log.i(TAG, "onCreate: width: " + imageWidth);
Log.i(TAG, "onCreate: height: " + imageHeight);
Log.i(TAG, "onCreate: type: " + imageType);// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.screen_capture, options);
Log.i(TAG, "onCreate: size: " + (bitmap.getByteCount() / 1024 / 1024) + " MB");// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, 100, 100);
Log.i(TAG, "onCreate: inSampleSize: " + options.inSampleSize);bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.screen_capture, options);
imageHeight = options.outHeight;
imageWidth = options.outWidth;
imageType = options.outMimeType;
Log.i(TAG, "onCreate: bitmap == null ? " + (null == bitmap));
Log.i(TAG, "onCreate: width: " + imageWidth);
Log.i(TAG, "onCreate: height: " + imageHeight);
Log.i(TAG, "onCreate: type: " + imageType);
Log.i(TAG, "onCreate: size: " + (bitmap.getByteCount() / 1024) + " KB");

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/231755.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows下wsl(ubuntu)ldconfig报错

错误 sudo ldconfig /sbin/ldconfig.real: Cant link /usr/lib/wsl/lib/libnvoptix_loader.so.1 to libnvoptix.so.1 /sbin/ldconfig.real: /usr/lib/wsl/lib/libcuda.so.1 is not a symbolic link解决&#xff1a; 处理 sudo ldconfig 报错 libcuda.so.1 is not a symbolic …

简单几步完成SVN的安装

介绍以及特点 SVN&#xff1a;Subversion&#xff0c;即版本控制系统。 1.代码版本管理工具 2.查看所有的修改记录 3.恢复到任何历史版本和已经删除的文件 4.使用简单上手快&#xff0c;企业安全必备 下载安装 SVN的安装分为两部分&#xff0c;第一部分是服务端安装&…

pytorch文本分类(三)模型框架(DNNtextCNN)

pytorch文本分类&#xff08;三&#xff09;模型框架&#xff08;DNN&textCNN&#xff09; 原任务链接 目录 pytorch文本分类&#xff08;三&#xff09;模型框架&#xff08;DNN&textCNN&#xff09;1. 背景知识深度学习 2. DNN2.1 从感知器到神经网络2.2 DNN的基本…

源码编译 METIS 以及 GKlib 在Linux ubuntu上

1. GKlib 构建 $ git clone --recursive gitgithub.com:Kleenelan/GKlib.git $ cd GKlib/ $ make config ccgcc openmpset $ make $ make install源码构建了 GKlib 的 openmp 版本&#xff0c;以便充分使用多核的算力&#xff1b; make config ccgcc openmpset 的效果图&#…

鸿蒙端H5容器化建设——JSB通信机制建设

1. 背景 2023年鸿蒙开发者大会上&#xff0c;华为宣布为了应对国外技术封锁的潜在风险&#xff0c;2024年的HarmonyOS NEXT版本中将不再兼容Android&#xff0c;并推出鸿蒙系统以及其自研的开发框架&#xff0c;形成开发生态闭环。同时&#xff0c;在更高维度上华为希望将鸿蒙…

智能优化算法应用:基于黑猩猩算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于黑猩猩算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于黑猩猩算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.黑猩猩算法4.实验参数设定5.算法结果6.参考文…

音视频学习(二十一)——rtmp收流(tcp方式)

前言 本文主要介绍rtmp协议收流流程&#xff0c;在linux上搭建rtmp服务器&#xff0c;通过自研的rtmp收流库发起取流请求&#xff0c;使用ffmpegqt实现视频流的解码与播放。 关于rtmp协议基础介绍可查看&#xff1a;https://blog.csdn.net/www_dong/article/details/13102607…

【机器学习】卷积神经网络(CNN)的特征数计算

文章目录 基本步骤示例图解过程 基本步骤 在卷积神经网络&#xff08;CNN&#xff09;中&#xff0c;计算最后的特征数通常涉及到以下步骤&#xff1a; 确定输入尺寸&#xff1a; 首先&#xff0c;你需要知道输入数据的尺寸。对于图像数据&#xff0c;这通常是 (batch_size, c…

Webpack安装及使用

win系统 全局安装Webpack及使用 前提&#xff1a;使用Webpack必须安装node环境&#xff0c;建议使用nvm管理node版本。 1&#xff1a;查看自己电脑是否安装了node 2&#xff1a;npm install webpack版本号 -g 3&#xff1a;npm install webpack-cli -g -g:表示全局安装 4&…

龙芯loongarch64服务器编译安装gcc-8.3.0

前言 当前电脑的gcc版本为8.3.0,但是在编译其他依赖包的时候,出现各种奇怪的问题,会莫名其妙的中断编译。本地文章讲解如何自编译安装gcc,替换系统自带的gcc。 环境准备 下载页面:龙芯开源社区网站 - LoongArch GCC 8.3 交叉工具链 - 源码下载源码包名称如:loongson-gnu…

2023-12-18 最大二叉树、合并二叉树、二叉搜索树中的搜索、验证二叉搜索树

654. 最大二叉树 核心&#xff1a;记住递归三部曲&#xff0c;一般传入的参数的都是题目给好的了&#xff01;把构造树类似于前序遍历一样就可&#xff01;就是注意单层递归的逻辑&#xff01; # Definition for a binary tree node. # class TreeNode: # def __init__(se…

强化产品联动:网关V7独家解决方案的三重优势

客户背景 某央企单位汇聚了众多业内优秀的工程师和科研人员&#xff0c;拥有先进的研发设施和丰富的研发经验&#xff0c;专注于为全球汽车行业提供创新和实用的解决方案。其研发成果不仅在国内市场上得到了广泛应用&#xff0c;也在国际市场上赢得了广泛的认可和赞誉。 客户需…

jconsole与jvisualvm

jconsole 环境变量配置好后 直接输入在cmd 输入jconsole 即可 jvisualvm cmd 输入jvisualvm jvisualvm 能干什么 监控内存泄露&#xff0c;跟踪垃圾回收&#xff0c;执行时内存、cpu 分析&#xff0c;线程分析… 运行&#xff1a;正在运行的 休眠&#xff1a;sleep 等待…

接口测试的工具(3)----postman+node.js+newman

1.安装newman&#xff1a;输入命令之后 一定注意 什么都不要操作 静静的等待结束就行了。 2.安装失败的对此尝试不行 在用下面的方法 解压一下就行了 3.验证是否成功 多次尝试是可以在线安装成功的

Unity中Shader URP最简Shader框架(ShaderGraph 转 URP Shader)

文章目录 前言一、 我们先了解一下 Shader Graph 怎么操作1、了解一下 Shader Graph 的面板信息2、修改Shader路径3、鼠标中键 或 Alt 鼠标左键 移动画布4、鼠标右键 打开创建节点菜单5、把ShaderGraph节点转化为 Shader 代码6、可以看出 URP 和 BuildIn RP 大体框架一致 二、…

隐私计算介绍

这里只对隐私计算做一些概念性的浅显介绍&#xff0c;作为入门了解即可 目录 隐私计算概述隐私计算概念隐私计算背景国外各个国家和地区纷纷出台了围绕数据使用和保护的公共政策国内近年来也出台了数据安全、隐私和使用相关的政策法规 隐私计算技术发展 隐私计算技术安全多方计…

C# WPF上位机开发(usb设备访问)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 目前很多嵌入式设备都支持usb访问&#xff0c;特别是很多mcu都支持高速usb访问。和232、485下个比较&#xff0c;usb的访问速度和它们基本不在一个…

unittest自动化测试框架讲解以及实战

为什么要学习unittest 按照测试阶段来划分&#xff0c;可以将测试分为单元测试、集成测试、系统测试和验收测试。单元测试是指对软件中的最小可测试单元在与程序其他部分相隔离的情况下进行检查和验证的工作&#xff0c;通常指函数或者类&#xff0c;一般是开发完成的。 单元…

工业数据的特殊性和安全防护体系探索思考

随着工业互联网的发展&#xff0c;工业企业在生产运营管理过程中会产生各式各样数据&#xff0c;主要有研发设计数据、用户数据、生产运营数据、物流供应链数据等等&#xff0c;这样就形成了工业大数据&#xff0c;这些数据需要依赖企业的网络环境和应用系统进行内外部流通才能…

【Python】—— NumPy基础及取值操作

NumPy基础及取值操作 第1关&#xff1a;ndarray对象第2关&#xff1a;形状操作第3关&#xff1a;基础操作第4关&#xff1a;随机数生成第5关&#xff1a;索引与切片 第1关&#xff1a;ndarray对象 任务描述 本关任务&#xff1a;根据本关所学知识&#xff0c;补全代码编辑器中…