安卓BitMap

290 阅读3分钟

一.简介

安卓系统中,BitMap可以理解为一张图片,比如说jpg,png格式的图片。

二.BitMap获取方式

BitMap可以通过BitMapFactory获得,BitMapFactory提供了多种方法进行获取BitMap,比如说 decodeFile(),decodeResource(),decodeStream(),分别从文件,res资源,IO流获取,但这么多方法都有一个共通点,就是会有一个Options参数,当使用无Options参数的方法时,该方法会委托有Options参数的方法去执行。

三.BitMap参数Options

3.1简介

在实际开发中,图片往往需要先进行缩小才能使用,这是因为安卓系统中每个程序分配到的内存有限,对图片进行缩小能一定程度避免OOM的出现。 图片的大小刚会好是ImageView的大小的情况不现实,图片往往会出现过大的问题,一般是需要先缩小图片才能将加载至ImageView中,而Options参数的功能就是设置图片缩小的倍数。

准确来说,是通过设置Options类里的int字段inSampleSize来设置缩小的倍数,当inSampleSize为n时,会将图片的长和宽都缩小至原来的1/n倍,换句话说,会把图片缩小至原来大小的1/n^2倍。举个栗子,比如说一张图片原大小为1024 * 1024,采用ARGB8888格式存储,那么这张图片的大小为4MB,那么inSampleSize设置为2后进行缩小,也就是让图片缩小4倍,缩小后的图片大小则为1MB。

需要注意的是,当inSampleSize的值小于1时,其作用等效于1,也就是不对图片进行缩小操作,此外,若inSampleSize的值若不是2的次方,系统会自动将修改为离原值最接近的2的次方,举个栗子,比如说inSampleSize的原值为5,离其最近的2的任意次方为4,那么inSampleSize就会被修改为4,不过这特性只适用于部分系统。

3.2inSampleSize的取值

一般来说,inSampleSize是根据BitMap的大小与ImageView的大小计算出来的,假设ImageView的大小为512 * 512,BitMap的大小为1024 * 1024,那么只需要将inSampleSize设置为(1024/512)=2就可以了,比较简单,当然了,实际开发中,像这种缩小后的BitMap的长宽都恰好与ImageView相同的理想情况,往往会出现缩小后的图片会被拉伸的情况。

那么如何获取BitMap的大小呢?

可以按照以下步骤来进行。

1.首先将新建一个Options实例option,将其的字段inJustDeodeBounds设置为true。

2.通过BitMapFactory任意方法获取BitMap,并将实例option作为参数。

3.成功获取BitMap后,获取BitMap的高和宽,与目标ImageView的大小进行比较,计算采样率inSampleSize的大小。

4.再将字段inJustDeodeBounds设置为false。

5.重新获取BitMap进行后续常规操作即可。

下面是使用Kotlin来获取BitMap的示例代码。

class MainActivity : FragmentActivity() {
...

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initView()
        val option=BitmapFactory.Options()
        option.inJustDecodeBounds=true
        val bitmap=BitmapFactory.decodeResource(resources,R.drawable.ic_track_play,option)
        val width=option.outWidth
        val height=option.outHeight
        
    }

    }

当将Options的字段inJustDecodeBounds设置为true时,BitMap只会去获取图片的长和宽,不会真正去加载图片,因此该加载只是轻量级的,不会对内存造成太大的负担,故可以放心使用。

参考资料

1.《Android开发艺术探索》任玉刚