12.1.2 图像的读取和输出
在Android中,图像文件的读取,都通过android.graphics.BitmapFactory类来处理的,使用BitmapFactory可以从不同的数据源中读取图像数据。比如,从图片文件中读取图像数据可以调用BitmapFactory.decodeFile函数:
Bitmap bitmap=BitmapFactory.decodeFile(
"/sdcard/sample.png");
图 12-1 九宫格图像的格式和显示效果
从资源文件中读取图像数据,则可以调用BitmapFactory.decodeResource函数:
Bitmap bitmap=BitmapFactory.decodeResouce(
R.drawable.sample);
但如果需要读取到内存中的文件图片过大,则可能导致内存溢出、应用崩溃。因此,在读取大图片时,需要控制读入的图像大小。使用android.graphics.BitmapFactory.Options对象可以设置图像读取的参数,在BitmapFactory.Options类中,in开头的参数表示控制图像读取的输入参数,比如,通过参数BitmapFactory.Options.inSampleSize可以控制图像的缩放比例:
//构造Options对象
BitmapFactory.Options options=new BitmapFactory.Options();
//将缩放比例设置为2,这意味着读入图像的长和宽都是原有尺寸的1/2
//在实际开发中,最好需要保证该参数是2的倍数
//通常会依据图像的实际大小和需要显示的大小比率进行推算
options.inSampleSize=2;
//读取图片,在这个过程中会进行缩放,降低图片尺寸
Bitmap bitmap=BitmapFactory.decodeFile(
"/sdcard/sample.png",options);
此外,在BitmapFactory.Options中以out开头的参数,是用来预取该图片文件中图像的基本信息的,包括长度、宽度、图片类型等。提前获取这些参数,对于选择如何读取图片有很大的帮助,比如,如果期望在读取图片时,能够根据图片的尺寸来决定读取的缩放比例,就需要预先了解该图片的尺寸信息。
获取这些信息,同样也是通过BitmapFactory.decodeFile函数来实现的。在函数执行后,相关参数会存储到BitmapFactory.Options对象中。为了区分执行BitmapFactory.decodeFile函数是为了获取图片信息,而不是读取图片数据,就需要将设置BitmapFactory.Options对象的inJustDecodeBounds参数设置为true:
//构造Options对象
BitmapFactory.Options options=new BitmapFactory.Options();
//将inJustDecodeBounds设置为true,表示仅仅是为了获取图片信息
options.inJustDecodeBounds=true;
//获取图片尺寸和图片类型
Bitmap bitmap=BitmapFactory.decodeFile(
"/sdcard/sample.png",options);
//后续可以通过图片尺寸来计算缩放比例等
int sacle=countSacle(options.outWidth, options.outHeight);
…
通过Bitmap.compress函数,可以将存放在内存中的图像数据压缩成png、gif、jpg等图片格式来输出。开发者既可以将图像信息输出到本地文件中,也可以直接输出到网络流中:
//打开一个文件,准备输出图像内容
OutputStream fileStream=openBitmapFile(…);
//按照100%质量的jpg格式输出
bitmap.compress(CompressFormat.JPEG,100,fileStream);
在实际开发中,通常都是使用该手段来控制图像大小。比如,在Android的原生图片管理应用中,在进行图像展示、图像剪切等交互时,都会计算采样比率,通过控制读取的图像大小来避免过多的内存开销。