http://my.oschina.net/ryanhoo/blog/88242 html
译者:Ryan Hoo java
来源:https://developer.android.com/develop/index.html
android
译者按: 在Google最新的文档中,提供了一系列含金量至关高的教程。由于种种缘由而不为人知,真是惋惜!Ryan将会细心整理,将之翻译成中文,但愿对开发者有所帮助。 缓存
本系列是Google关于展现大Bitmap(位图)的官方演示,能够有效的解决内存限制,更加有效的加载并显示图片,同时避免让人头疼的OOM(Out Of Memory)。
性能
------------------------------------------------------------------------------------- spa
译文: .net
图像能够有各类各样的形状和大小。在不少状况下,它们每每会比典型的应用UI界面所须要的更大。例如,系统的Gallery程序展现使用Android设备的摄像头拍摄的照片的分辨率每每要远高于设备的屏幕密度。
读取Bitmap(位图)的尺寸和类型 翻译
BitmapFactory提供了几种解码方式(decodeByteArray(), decodeFile(), decodeResource()等等),以便从多种资源中建立一个Bitmap(位图)对象。能够根据你的图片数据来源选择最合适的解码方式。这些方法视图为构造Bitmap对象分配内存,所以很容易致使OutOfMemory(OOM)异常。每一种解码方式都有额外的特征,你能够经过BitmapFactory.Options类类指定解码方法。在解码图片的时候设置inJustDecodeBounds属性为true,能够避免内存分配,返回的bitmap对象为null却能够设置outWidth, outHeight和outMimeType。这项技术容许你在建立Bitmap(并分配内存)以前读取图片的尺寸和类型。 code
BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(getResources(), R.id.myimage, options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; String imageType = options.outMimeType; |
|
例如,若是最终只是要在ImageView中显示一张128*96px大小的缩略图,直接加载1024*768px的图片是很是不值得的。 orm
为了告诉解码器如何对图像进行采样,加载更小版本的图片,须要在BitmapFactory.Options对象中将inSampleSize设置为true。例如,一张分辨率为2048*1536px的图像使用inSampleSize值为4的设置来解码,产生的Bitmap大小约为512*384px。相较于完整图片占用12M的内存,这种方式只需0.75M内存(假设Bitmap配置为ARGB_8888)。这里有一个方法用来计算基于目标高宽的sample size的值:
public static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { if (width > height) { inSampleSize = Math.round((float)height / (float)reqHeight); } else { inSampleSize = Math.round((float)width / (float)reqWidth); } } return inSampleSize; }
提示:使用2的次幂来设置inSampleSize值可使解码器执行地更加迅速、更加高效。可是,若是你想在内存或者硬盘上缓存一个调整过大小的图片,一般仍是解码到合适的图片尺寸更加节省空间。
要使用这个方法,首先要使用inJustDecodeBounds为true来解码尺寸信息,将options传递过去使用新的inSampleSize值再次解码而且要将inJustDecodeBounds值设置为false。
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); }
|
mImageView.setImageBitmap( decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));你能够根据须要,按照相似的解码过程,采用适当的BitmapFactory.decode*方法从其余资源中解码Bitmap。 |