1

我需要讓用戶從他們的圖庫中打開特定的相冊,並讓他們用圖像做些什麼。Android - 避免從圖庫中提取圖像的內存泄漏

爲了獲取從相冊中的圖片,我使用的是:
Bitmap bitmap = MediaStore.Images.Media.getBitmap(contentResolver, uri).

一切工作正常,但如果這張專輯包含了很多圖片,它結束了一個trowing OutOfMemoryException.
現在的事實,我知道如何基於Android guidelines緩解這個問題,但問題是我已經檢索到原始位圖getBitmap()

那麼,是否有可能檢索圖像的字節數組格式或輸入流格式和在將其分配給內存之前將其縮小,以避免內存泄漏? (以與Android指南相同的方式提供建議)

回答

0

所以,在我的手裏有一個形象Uri我想找回它的InputStream,並在內存分配,以避免之前縮小圖像OutOfMemoryException

解決方案:
要從烏里檢索的InputStream,你必須把這個:

InputStream stream = getContentResolver().openInputStream(uri); 

然後在loading bitmaps efficiently以下的Android建議,你只需要調用BitmapFactory.decodeStream(),並通過BitmapFactory.Options作爲參數。

完整的源代碼:

imageView = (ImageView) findViewById(R.id.imageView); 

Uri uri = Uri.parse("android.resource://com.testcontentproviders/drawable/"+R.drawable.test_image_large); 
Bitmap bitmap=null; 
    try { 
     InputStream stream = getContentResolver().openInputStream(uri); 
     bitmap=decodeSampledBitmapFromStream(stream, 150, 100); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } 

imageView.setImageBitmap(bitmap); 

的輔助方法:

public static Bitmap decodeSampledBitmapFromStream(InputStream stream, 
      int reqWidth, int reqHeight) { 

    // First decode with inJustDecodeBounds=true to check dimensions 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeStream(stream, null, options); 

    // Calculate inSampleSize 
    options.inSampleSize = calculateInSampleSize(options, reqWidth, 
       reqHeight); 

    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    return BitmapFactory.decodeStream(stream, null, 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) { 
     if (width > height) { 
      inSampleSize = Math.round((float) height/(float) reqHeight); 
     } else { 
      inSampleSize = Math.round((float) width/(float) reqWidth); 
     } 
    } 
    return inSampleSize; 
} 
0

您已經確定了一個非常好的解決方案。如果您想跳過通過MediaStore將圖像拖入Bitmap的步驟,請嘗試使用ImageView.setImageUri()

+0

你好,謝謝你的評論。嘗試在縮放之前將Uri傳遞給ImageView也會導致OutOfMemoryException,它的圖像太大。但是你爲我開闢了一個新的選擇,並且基於Uri現在我能夠檢索InputStream並縮小圖像。我會很快發佈解決方案。 – 2012-07-27 11:36:28