« 主页

安卓中的图片处理

版权声明:眯眼探云原创,可随意转载,请保留该版权声明及链接:https://tyun.fun/post/07.decode-bitmap-android/

最近发现组员们对图片的处理始终有一些理解不清楚的地方,所以稍微整理了一个简单的分享。主要是在安卓中对位图处理的一些理论知识。

一张图片是如何使用内存的

按 ARGB_8888 这种配置(最常用的配置)来描述每一个像素的话,一个像素占用的内存是4字节,其中 Alpha, Red, Green, Blue 各占一字节。那么 1000 x 1000 的图片占用的空间是:1000 x 1000 x 4 = 4,000,000 字节。而现在手机上的照片,2000 x 4000 以上的分辨率(我随便看了一张我手机中的照片的分辨率)应该是很常见,所以,就要占掉32MB以上的内存。而经过压缩过后,也就占2、3MB的存储空间。

所以这就是现实的情况:

一张几MB的jpg图,一加载到内存中,很容易就撑爆了内存。

如何解决内存问题

在解码图片的时候,有个参数名字叫 BitmapFactory.Options.inSampleSize。这个参数的作用是啥呢?是在解码的时候降低采样大小。比如,2000 x 2000 的图片,我使用 2 的采样大小,那么就可以得到 1000 x 1000 的图片。使用 4 的采样大小,就变成了 500 x 500 的图片。这样,加载图片的内存压力一下就降低了。

它是如何工作的呢?

比如一个图片是 2 x 2,而对其使用 2 的采样大小这个参数,而这个样本参数,会用于图片的 X/Y 两个轴,所以最终的结果就是,只剩一个像素了。

这样肯定会降低最终显示的图片的质量,不过没关系,因为大多数情况下我们本来就只需要一张小图。

而这里还有一个引申问题:在解码图片之前,我如何知道一张图片的尺寸呢?

解码的时候有个属性(BitmapFactory.Options.inJustDecodeBounds),可以让你只获取图片的相关属性(尺寸,元数据等),而不去进行实际的解码。

如何显示完整质量的图片

如果一张图片很大,又需要完整并清晰的把它显示出来,就需要用到专门的技术。比如按区域解码:既然这张图太大了,那么我就每次解码一个区域,这样就不会引起 OOM 了。并且没有显示在屏幕上的部分,还可以考虑回收掉内存再利用。

不过这一般就是专业图片浏览器要做的事情了,在一般的 APP 中,显示缩略图通常完全能够满足需求了。