android 加载大图片处理
2014-08-13 21:07
183 查看
转载自:http://blog.csdn.net/xu_fu/article/details/8262153
在Android中显示图片一般使用ImageView,通过setImageBitmap()、setImageResource()等方法指定要显示的方法,而这些方法最终都会调用到BitmapFactory.decode()方法来生成一个Bitmap进行显示。对于一般的小图片这样使用没有什么问题,因为垃圾回收器会及时将不用的图片进行回收,但连续加载大图片的时候就会发生典型的OOM问题,也就是内存溢出,这是因为在Android系统中虚拟机为每一个应用程序都分配了指定内存大小,如果使用超出了这个限制就会发生内存溢出导致程序崩溃。
因此要避免OOM的问题就需要对大图片的加载进行管理,主要通过缩放来减小图片的内存占用。
1、Bitmap的缩放
生成Bitmap都要通过BitmapFactory的decode()方法,使用此方法时可以传入一个解析参数BitmapFactory.Option来对控制解析过程,比如获得长宽、改变采样率、改变采样格式等。而对Bitmap的缩放就是通过改变采样率来实现的,具体操作如下:
1)计算实际采样率
[java] view
plaincopyprint?
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)由得到的采样率对图片进行解析
[java] view
plaincopyprint?
public static Bitmap decodeSampledBitmapFromFile(String filename,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filename, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filename, options);
}
这样就可以对图片实现缩放的功能了,缩放的内存大小是实际的1/(samplesize^2)。但这里还有一个问题,就是实际解析图片的时候是从硬盘上读取的,当图片较大的时候这个解析时间是不确定的,如果直接在UI线程中执行,会观察到明显的停顿,再时间长一点就ANR了,所以需要将图片解析的过程放在异步操作了,可以单开一个线程,也可以使用系统提供的异步任务类AsyncTask,示例如下:
[java] view
plaincopyprint?
class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private String data = null;
public BitmapWorkerTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
// Decode image in background.
@Override
protected Bitmap doInBackground(String... params) {
data = params[0];
return decodeSampledBitmapFromFile(data, 100, 100));
}
// Once complete, see if ImageView is still around and set bitmap.
@Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
这里需要传入ImageView,当后台图片解析完成后就会将图片加载进行显示。
关于Bitmap图片的加载Google官网上有详细的教程讲解,除了解析还有缓存的解决方案
http://developer.android.com/intl/zh-CN/training/displaying-bitmaps/index.html
这里主要介绍了使用BitmapFactory.Option来对图片进行缩放。
在Android中显示图片一般使用ImageView,通过setImageBitmap()、setImageResource()等方法指定要显示的方法,而这些方法最终都会调用到BitmapFactory.decode()方法来生成一个Bitmap进行显示。对于一般的小图片这样使用没有什么问题,因为垃圾回收器会及时将不用的图片进行回收,但连续加载大图片的时候就会发生典型的OOM问题,也就是内存溢出,这是因为在Android系统中虚拟机为每一个应用程序都分配了指定内存大小,如果使用超出了这个限制就会发生内存溢出导致程序崩溃。
因此要避免OOM的问题就需要对大图片的加载进行管理,主要通过缩放来减小图片的内存占用。
1、Bitmap的缩放
生成Bitmap都要通过BitmapFactory的decode()方法,使用此方法时可以传入一个解析参数BitmapFactory.Option来对控制解析过程,比如获得长宽、改变采样率、改变采样格式等。而对Bitmap的缩放就是通过改变采样率来实现的,具体操作如下:
1)计算实际采样率
[java] view
plaincopyprint?
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)由得到的采样率对图片进行解析
[java] view
plaincopyprint?
public static Bitmap decodeSampledBitmapFromFile(String filename,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filename, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filename, options);
}
这样就可以对图片实现缩放的功能了,缩放的内存大小是实际的1/(samplesize^2)。但这里还有一个问题,就是实际解析图片的时候是从硬盘上读取的,当图片较大的时候这个解析时间是不确定的,如果直接在UI线程中执行,会观察到明显的停顿,再时间长一点就ANR了,所以需要将图片解析的过程放在异步操作了,可以单开一个线程,也可以使用系统提供的异步任务类AsyncTask,示例如下:
[java] view
plaincopyprint?
class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private String data = null;
public BitmapWorkerTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
// Decode image in background.
@Override
protected Bitmap doInBackground(String... params) {
data = params[0];
return decodeSampledBitmapFromFile(data, 100, 100));
}
// Once complete, see if ImageView is still around and set bitmap.
@Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
这里需要传入ImageView,当后台图片解析完成后就会将图片加载进行显示。
关于Bitmap图片的加载Google官网上有详细的教程讲解,除了解析还有缓存的解决方案
http://developer.android.com/intl/zh-CN/training/displaying-bitmaps/index.html
这里主要介绍了使用BitmapFactory.Option来对图片进行缩放。
相关文章推荐
- Android 利用多线程异步加载图,并把图片处理成圆角,并更新视图
- Android应用程序开发之图片操作(二)——工程图片资源的加载及OOM的处理
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- (4.1.21.4)Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- Android 加载打图片出现OOM异常的处理方式
- android处理加载大图片内在溢出问题
- Android Bitmap 全面解析(二)加载多张图片的缓存处理 ...
- [Android实例] Android Bitmap 全面解析(二)加载多张图片的缓存处理
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- Android开发之图片处理专题(三):利用ThreadPoolExcutor线程池实现多图片的异步加载
- android使用LruCache对listview加载图片时候优化处理
- Android Bitmap 全面解析(二)加载多张图片的缓存处理
- Android Bitmap 全面解析(二)加载多张图片的缓存处理 ...
- android ImageView关于网络加载图片圆形处理
- android ListView 重写 SimpleAdapter 显示图片 异步加载及文字处理
- Android加载大量网络图片出现内存溢出的处理
- Android Bitmap 全面解析(二)加载多张图片的缓存处理
- android图片加载处理
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类