Android-Bitmap压缩策略

本文讲述了Android中BitmapFactory的decodeFile,decodeResource,decodeStream和decodeByteArray方法,重点介绍了BitmapFactory.Options的inSampleSize参数用于按采样率缩放图片,以及如何利用inJustDecodeBounds参数高效预加载图片的宽高信息。
摘要由CSDN通过智能技术生成

decodeFile,decodeResource,decodeStreamdecodeByteArray,分别从文件系统,
资源,输入流和字节数组中加载出一个Bitmap对象,其中
decodeFile,decodeResource又间接调用了decodeStream方法,这四类方法最终是
在Android的底层实现的,对应着BitmapFactory类的几个native方法。

2.BitmapFactory.Options的参数

inSampleSize参数
上述四类方法都支持BitmapFactory.Options参数,而Bitmap的按一定采样率进行缩
放就是通过BitmapFactory.Options参数实现的,主要用到了inSampleSize参数,即
采样率。通过对inSampleSize的设置,对图片的像素的高和宽进行缩放。

inSampleSize=1,即采样后的图片大小为图片的原始大小。小于1,也按照1来计
算。 当inSampleSize>1,即采样后的图片将会缩小,缩放比例为1/(inSampleSize
的二次方)。

例如: 一张1024 ×1024像素的图片,采用ARGB8888格式存储,那么内存大小
1024×1024×4=4M。如果inSampleSize=2,那么采样后的图片内存大小:
512×512×4=1M。

注意: 官方文档支出,inSampleSize的取值应该总是2的指数,如1,2,4,8等。
如果外界传入的inSampleSize的值不为2的指数,那么系统会向下取整并选择一个
最接近2的指数来代替。比如3,系统会选择2来代替。当时经验证明并非在所有
Android版本上都成立。

关于inSampleSize取值的注意事项: 通常是根据图片宽高实际的大小/需要的宽高
大小,分别计算出宽和高的缩放比。但应该取其中最小的缩放比,避免缩放图片太
小,到达指定控件中不能铺满,需要拉伸从而导致模糊。

例如: ImageView的大小是100×100像素,而图片的原始大小为200×300,那么宽
的缩放比是2,高的缩放比是3。如果最终inSampleSize=2,那么缩放后的图片大小
100×150,仍然合适ImageView。如果inSampleSize=3,那么缩放后的图片大小小
ImageView所期望的大小,这样图片就会被拉伸而导致模糊。

inJustDecodeBounds参数
我们需要获取加载的图片的宽高信息,然后交给inSampleSize参数选择缩放比缩
放。那么如何能先不加载图片却能获得图片的宽高信息,通过
inJustDecodeBounds=true,然后加载图片就可以实现只解析图片的宽高信息,并
不会真正的加载图片,所以这个操作是轻量级的。当获取了宽高信息,计算出缩放
比后,然后在将inJustDecodeBounds=false,再重新加载图片,就可以加载缩放后
的图片。

注意: BitmapFactory获取的图片宽高信息和图片的位置以及程序运行的设备有
关,比如同一张图片放在不同的drawable目录下或者程序运行在不同屏幕密度的设
备上,都可能导致BitmapFactory获取到不同的结果,和Android的资源加载机制
有关

3.高效加载Bitmap的流程

①将BitmapFactory.OptionsinJustDecodeBounds参数设为true并加载图片。
②从BitmapFactory.Options中取出图片的原始宽高信息,它们对应于outWidth
outHeight参数。

③根据采样率的规则并结合目标View的所需大小计算出采样率inSampleSize
④将BitmapFactory.OptionsinJustDecodeBounds参数设为false,然后重新加载
图片。

三、Bitmap高效加载的代码实现

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
//加载图片
BitmapFactory.decodeResource(res,resId,options);
//计算缩放比
options.inSampleSize = calculateInSampleSize(options,reqHeight,reqWidth);
//重新加载图片
options.inJustDecodeBounds =false;
return BitmapFactory.decodeResource(res,resId,options);
}

private static int calculateInSampleSize(BitmapFactory.Options options, int reqHeight, int reqWidth) {
int height = options.outHeight;
int width = options.outWidth;
int inSampleSize = 1;
if(height>reqHeight||width>reqWidth){
int halfHeight = height/2;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

《960全网最全Android开发笔记》

《379页Android开发面试宝典》

《507页Android开发相关源码解析》

因为文件太多,全部展示会影响篇幅,暂时就先列举这些部分截图

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!*

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值