解决Android 加载大图片OOM
图片在Android 占用内存计算
假如一张图的像素为100×200,那么他在内存中占用的内存为:
100×200(像素点) × 4(每个像素点占用的内存,默认为4.)
public Bitmap.Config inPreferredConfig = Bitmap.Config.ARGB_8888;
我们可以通过设置android.graphics.BitmapFactory.Options#inPreferredConfig 来改变加载时一个像素占用的字节
解决加载超大图片OOM
原理是我们图片控件能现实的像素有限,我们可以首先不占用内存的得到图片的宽高,然后和我们控件的宽高做一个比例压缩,这样就可以防止OOM.
只获取图片的宽高,不加载进入内存:
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;
计算SampleSize:
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 heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高 // 一定都会大于等于目标的宽和高。 inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize;
}
加载大图:
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); // 调用上面定义的方法计算inSampleSize值 options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // 使用获取到的inSampleSize值再次解析图片 options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options);
}
BitmapFactory.Options 一些变量的含义:
inSampleSize
/*** If set to a value > 1, requests the decoder to subsample the original* image, returning a smaller image to save memory. The sample size is* the number of pixels in either dimension that correspond to a single* pixel in the decoded bitmap. For example, inSampleSize == 4 returns* an image that is 1/4 the width/height of the original, and 1/16 the* number of pixels. Any value <= 1 is treated the same as 1. Note: the* decoder uses a final value based on powers of 2, any other value will* be rounded down to the nearest power of 2.*/public int inSampleSize;
inSampleSize 表示压缩的比例,宽高同时都会被压缩,所以,如果你设置的值为4的时候,那么压缩后的占用内存会是原来的1/16(4×4)
代码:
BitmapFactory.Options options = new BitmapFactory.Options();Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/img_big.jpg", options);int allocationByteCount = bitmap.getAllocationByteCount();Log.d(TAG, "onCreateView: allocationByteCount " + allocationByteCount);bitmaps.add(bitmap);options = new BitmapFactory.Options();options.inSampleSize = 4;Bitmap bitmap2 = BitmapFactory.decodeFile("/sdcard/img_big.jpg", options);int allocationByteCount2 = bitmap2.getAllocationByteCount();Log.d(TAG, "onCreateView: allocationByteCount2 " + allocationByteCount2);
打印:
2021-04-29 22:53:57.763 10745-10745/com.pipiyang.cn03 D/BigImageFragment: onCreateView: allocationByteCount 96000000
2021-04-29 22:53:58.917 10745-10745/com.pipiyang.cn03 D/BigImageFragment: onCreateView: allocationByteCount2 6000000
inJustDecodeBounds
/*** If set to true, the decoder will return null (no bitmap), but* the <code>out...</code> fields will still be set, allowing the caller to* query the bitmap without having to allocate the memory for its pixels.*/public boolean inJustDecodeBounds;
表示只是获取图片的宽高信息,并不会加载到内存中去。
参考:
https://www.jianshu.com/p/da754f9fad51
解决Android 加载大图片OOM相关推荐
- Android加载大图片OOM异常解决
Android加载大图片OOM异常解决 参考文章: (1)Android加载大图片OOM异常解决 (2)https://www.cnblogs.com/jevan/archive/2012/07/05 ...
- 【转载】Android加载大图片OOM异常解决
官方资料: https://developer.android.com/topic/performance/graphics/load-bitmap 思路 先测试未知来源图片的尺寸和MIME文件类型; ...
- Android手机内存图片读取,有效解决Android加载大图片内存溢出的问题
今天在交流群里,有人问我他经常遇到加载图片时内存溢出的问题,遇到的情况还是在自己的测试机或者手机里没有问题,做好了, 到了客户手机里就内存溢出了.其实有时候不同的手机和不同的系统对内存的要求不一样,尤 ...
- Android加载大图片不OutOfMemoryError
Android加载图片时,对于分辨率小,配置低的机子,很容易发生OutOfMemoryError.手机的内存比图片的大很多,怎么会这样? 在设置Android虚拟机的内存时: RAM:模拟器的内存空间 ...
- Android 加载大图片
我们在做开发的时候总是会不可避免的遇到加载图片的情况,当图片的尺寸小于ImageView的尺寸的时候,我们当然可以很happy的去直接加载展示.但是如果我们要加载的图片远远大于ImageView的大小 ...
- Android加载大图片(压缩)
转载自http://blog.csdn.net/junjx/article/details/7798604 在Android开发中,我们经常需要加载图片.但是图片的尺寸往往会很大,如果我们要的是比较小 ...
- 关于 android 加载 res 图片 out of memory 问题 解决 同样适用于 sd卡图片
2019独角兽企业重金招聘Python工程师标准>>> 发现android 加载res图片如果过多也会崩溃 android 也是使用 Bitmap bm = BitmapFacto ...
- Android 加载本地图片(文件管理器中的图片墙)
Android 加载本地图片(文件管理器中的图片墙) --关于图片墙的一些感悟与疑问,希望大家共同探讨. (By伊叶也) 图片显示及监听 1.图片显示:基本上就5种显示形式(如果同时嵌入5种形式,采用 ...
- 解决ImageLoader加载HTTPS图片证书校验异常问题
解决ImageLoader加载HTTPS图片证书校验异常问题 参考文章: (1)解决ImageLoader加载HTTPS图片证书校验异常问题 (2)https://www.cnblogs.com/cs ...
最新文章
- 你不知道的Vue响应式原理
- 剑指 Offer 43. 1~n整数中1出现的次数
- selenium 状态码521_sqlmap对状态码404处理的bug
- HikariConfig配置详解
- java中使用openssl生成的rsa公私钥进行数据加解密_使用openssl生成RSA公钥和私钥对...
- sql count用法_SQL学习笔记3:count(*)函数
- [渝粤教育] 南开大学 思辨式英文写作 参考 资料
- 转]从一个男人关注的事情上 可以看出他的修养和抱负
- ufvm可以读哪些网格_墙面开裂原因有哪些?钢筋网和网格布怎么用?
- Script 入门实践
- mysql的底层数据结构_MySQL索引底层数据结构实现原理
- MFC 驱动加载工具(安装/运行/停止/卸载)
- Android Netd
- Material Design学习
- 学法减分拍照识题小程序开发
- Redmi K20 安卓9跨版本刷第三方ROM
- Hilt的使用(动态模块)四
- Android8.0源码解析——Activity的启动过程
- i5 13490f参数 怎么样 i5 13490f功耗 酷睿i513490f什么水平级别
- 天载优配解读全商场亏钱效应浓郁
热门文章
- 海天 oracle,Oracle执行计划详解
- 00截断上传绕过_【文件上传与解析】文件上传与解析漏洞总结v1.0
- portainer忘记用户名密码_【20201122】做个用户管理系统(6)——忘记密码页面、重置密码方式页面的模板制作...
- python中import numpy_Python开发:NumPy学习(一)ndarray数组
- 线性最小二乘问题求解的豪斯荷尔德法C实现
- oracle 一致性读数量,ORACLE 一致性读原理记录
- ffmpeg php win32,解决PHP5.3.x下ffmpeg安装配置问题
- EF 查看生成的SQL语句
- scala break continue
- 比较难理解的知识汇集