- 既能获得图片大小,由于后续操作
- 又成功避免了去解析图片,导致程序 OOM 而崩溃 。
好了,现在给出具体的实现:
文章插图
大家可能发现,这里只将 inJustDecodeBounds 设为true却没有改回false,这是因为获得 Options 只是图片压缩的第一步,我们在后续方法中将会进行修改
文章插图
四、如何进行压缩我们继续看 Options 的构成 。我们发现,其中有个名为 inSampleSize 的数据成员,他就是关键所在,那么他有着什么意义呢?
这里我给大家举个例子,比如我这有张 4000*1000 像素的图片:
- 当我们把 inSampleSize 的值设为 4时,最后生成出来的图片大小将会是:1000 x 250 像素
- 当我们把inSampleSize 的值设为5时,最后生成出来的图片大小将会是:800 x 200 像素 。这是个什么概念?
- 如果原图 2MB,那么当 inSampleSize 赋值为4加载时就只需要 0.125MB
- 那 如果 inSampleSize 赋值为 5 呢?只需要 0.08 MB!连100k 都不到的小图啊!
文章插图
我们发现,这里我先计算出了,原图尺寸与目标大小大比例,在三目运算符中,将inSamplesize 赋值为较大的一个 。为什么不用小的那一个呢?这里我就卖个关子,大家可以在评论区中发表自己的想法
五、生成目标图片经过前面的两个步骤,想必大家已经能勾勒处这最后一步的做法了,思路非常简单:
- 先生成一个 Options对象
- 将 Options 的 inJustDecodeBounds设置为true
- 接着调用方法一calculateOptionsById获得原图尺寸到Options中
- 调用方法三calculateInSamplesizeByOptions 获得相应的inSampleSize 对象
- 将 Options的inJustDecodeBounds改回 false
- 再次调用 decode...()方法(这里是 decodeResource )获得压缩后的 Bitmap对象
文章插图
非常棒,我们赶紧看看效果:
文章插图
太棒了,几乎和原图效果一摸一样,但软件运行的流畅性确大大提高了!但是,这真的就完美了吗?
最求完美的我们可能会有个想法:如果调用我们方法的人,或者说特殊时候的我们 。不想用这个已经写好的 decodeBitmapById方法,而是像自己通过前两个方法:calculateOptionsById calculateInSamplesizeByOptions 来实现图片压缩功能,这是问题就出现了:
- 调用 calculateOptionsById 前可能忘记,设置 inJustDecodeBound 为 true,进而导致计算超大图时,直接发生 OOM
- 调用完 calculateInSamplesizeByOptions 后可能忘记,设置inJustDecodeBounds 为 false,进而导致无法获得Bitmap 对象,一脸懵逼
- 啥都做了结果调用完 calculateInSamplesizeByOptions 没把没回的值赋给 options.inSampleSize,白忙活一场
首先,在calculateOptionsById中,默认将 options.inJustDecodeBounds 设置为true:
文章插图
其次,在 calculateInSamplesizeByOptions最后,默认将 options.inJustDecodeBounds设置为false:
文章插图
为什么不在该方法后面,对 options.inSampleSize进行赋值呢?这主要是防止,有时我们可能只想得到计算相应比例来做其他操作,而不想改变原有属性,所以是否赋值,就交给用户去选择吧
总结好了,到这里为止,历时有关图片压缩的所有坑坑洼洼都已经总结好了,我们从头理以边思路:
- 借助options.inJustDecodeBounds 参数赋值true时,不生成图片的特性,将原图尺寸保存在 Options 中
- 通过 options 中原图尺寸与目标(控件)尺寸的比例,对 options.inSampleSize 进行设置
- 生成目标图片
- 压缩的问题解决了,但是每次打开图片都压缩也太麻烦了!下面我将针对这个问题进行更有效地解决,有兴趣可以继续关注 _yuanhao 的编程世界
推荐阅读
- 祁门红茶价格表及图片
- 滇红茶鉴别图片
- 滇红茶种类名称图片大全
- 滇红茶种类名称图片
- 梦见弖优芽美图片 狂赌之渊梦见弖优芽美
- 正宗祁门红茶图片
- 人和猪的照片 人面对猪图片
- 小种红茶种类图片
- 宜兴红茶品之味的价格和图片
- 宜兴红茶原生态价格和图片