您的位置:首页 > 移动开发 > Android开发

android开发步步为营之50:android关于加载大图片java.lang.OutOfMemoryError错误的解决

2014-12-10 17:15 696 查看


http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
官方有一篇文章是如下这么解决的,通过Resource加载后压缩图片大小

//方法一:通过Resource加载

mImageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));

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);

}

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) {

final int halfHeight = height / 2;

final int halfWidth = width / 2;

// Calculate the largest inSampleSize value that is a power of 2 and keeps both

// height and width larger than the requested height and width.

while ((halfHeight / inSampleSize) > reqHeight

&& (halfWidth / inSampleSize) > reqWidth) {

inSampleSize *= 2;

}

}

return inSampleSize;

}

如果不是通过Resource,而是通过Drawable对象,比如获取手机所有安装的应用图标,通过下面这张方法来压缩图片

//方法二:通过Drawable对象加载

//获取压缩后的图标

private Drawable getAppIcon(PackageManager pm, ApplicationInfo applicationInfo) {

try {

//oom报错,采用下面的方法

Drawable drawable = pm.getApplicationIcon(applicationInfo);

Bitmap bm = CommonUtils.drawableToBitmap(drawable);

ByteArrayOutputStream baos = new ByteArrayOutputStream();

bm.compress(Bitmap.CompressFormat.PNG, 100, baos);

byte[] data = baos.toByteArray();

//压缩前

int size1=bm.getByteCount();

BitmapFactory.Options opts = new BitmapFactory.Options();

opts.inJustDecodeBounds = true;

BitmapFactory.decodeByteArray(data, 0, data.length, opts);

opts.inSampleSize = computeSampleSize(opts, -1, 100 * 100);

//这里一定要将其设置回false,因为之前我们将其设置成了true

opts.inJustDecodeBounds = false;

Bitmap bmNew =BitmapFactory.decodeByteArray(data, 0, data.length, opts);

//压缩后,测试过4194304Byte的压缩成16384Byte压缩效果明显

int size2=bmNew.getByteCount();

return new BitmapDrawable(bmNew);

//end

}catch(Exception e)

{

Log.e("DataCenter.getAppIcon.Exception", "Exception", e);

}

catch (OutOfMemoryError e) {

// TODO: handle exception

Log.e("DataCenter.getAppIcon.OutOfMemoryError", "OutOfMemoryError", e);

//图片太大就换一个默认的小图标给用户

return new BitmapDrawable(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher_default));

}

return null;

}

public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {

int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);

int roundedSize;

if (initialSize <= 8) {

roundedSize = 1;

while (roundedSize < initialSize) {

roundedSize <<= 1;

}

} else {

roundedSize = (initialSize + 7) / 8 * 8;

}

return roundedSize;

}

private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {

double w = options.outWidth;

double h = options.outHeight;

int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));

int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));

if (upperBound < lowerBound) {

return lowerBound;

}

if ((maxNumOfPixels == -1) && (minSideLength == -1)) {

return 1;

} else if (minSideLength == -1) {

return lowerBound;

} else {

return upperBound;

}

}

public static Bitmap drawableToBitmap(Drawable drawable) {

Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888

: Bitmap.Config.RGB_565);

Canvas canvas = new Canvas(bitmap);

//canvas.setBitmap(bitmap);

drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());

drawable.draw(canvas);

return bitmap;

}

BitmapFactory提供多种Decode方法,大家根据需要来使用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐