2015-08-28 84 views
1

根據我的要求,我有一個用於調整位圖圖像大小的簡單類。有負責它的簡單方法如下:位圖調整大小會導致內存不足

public static Bitmap ResizeRichImages(Bitmap bitmap, Context mContext){ 
     try { 
     float originalBitmapWidth = bitmap.getWidth(); 
     float originalBitmapHeight = bitmap.getHeight(); 
     float originalAspectRatio = originalBitmapWidth/originalBitmapHeight; 
     double width_percentage = (0.05*screenWidthPixels(mContext)); 
     float newWidth = (float)((int)screenWidthPixels(mContext)-width_percentage); 
     float newBitmapWidth = newWidth; 
     float newBitmapHeight = newBitmapWidth/originalAspectRatio; 
     bitmap = Bitmap.createScaledBitmap(bitmap, (int) newWidth, (int)newBitmapHeight, false); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return bitmap; 

    } 

這是我如何調用此方法:

String URL = "https://maps.googleapis.com/maps/api/staticmap?center=-33.86527274921529,151.2050531328867&zoom=15&size=640x360&sensor=false&markers=color:blue%7Clabel:!%7C-33.86527274921529,151.2050531328867"; 

try { 
bmp = Picasso.with(ViewStory.this).load(URL) 
                  .get(); 
bmp = ImageController.ResizeRichImages(bmp, ViewStory.this); 
               } catch (Exception e) { 
                e.printStackTrace(); 
               } 

但是,幾乎每一個我收到了內存異常,同時調用時間ResizeRichImages方法。我哪裏錯了?

+0

何去何從是screenWidthPixels(mContext) –

+0

請檢查:http://stackoverflow.com/questions/26296344/out-of-memory-error-for-files-greater-than-3mb-though-upload-using-chunk/26296433#26296433 – pbespechnyi

+0

''android:largeHeap「'只隱藏問題......非常普遍的**你不應該使用它** ...但它通常被糟糕的程序員使用(沒有知識和技能)和noobs – Selvin

回答

-1

你還沒有告訴我們你的位圖有多大。也許它只是用盡所有的空閒內存,特別是如果你有其他大型位圖(或其他)佔用了大部分空間。

我會嘗試在小位圖上運行該過程,並且newBitmapWidth和newBitmapHeight減少到現在的十分之一。如果這消除了這個異常,那麼在你能夠處理全尺寸之前,你很確定你需要優化你的內存使用。

+0

該圖像可以與您從https://maps.googleapis.com/maps/api/staticmap?center=-33.86527274921529,151.2050531328867&zoom=15&​​size=640x360&sensor=false&markers=color:blue%7Clabel:!%下載的圖片一樣大7C-33.86527274921529,151.2050531328867 – kittu88

0
  • 取而代之,在清單中使用largeHeap選項應始終是最後一個選項,您可以嘗試壓縮,如下面的代碼片段所示。

*

byteArrImage = NULL;

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
if(data != null) thumbnail = (Bitmap) data.getExtras().get("data"); 
if(thumbnail != null) { 
    //thumbnail.compress(Bitmap.CompressFormat.PNG, 85, baos); 
    thumbnail.compress(Bitmap.CompressFormat.JPEG, 85, baos); 
    byteArrImage = baos.toByteArray(); 
    uploadImageToServer(); 
} 
0

我之前得到了同樣的錯誤,但經過一番搜索,我發現另一種方式來調整大位圖圖像。當您使用大圖像的位圖時,必須使用BitmapFactory.Options.inSampleSize縮放圖像。樣本大小是任一維度中與解碼位圖中的單個像素對應的像素數量。當你使用inSampleSize = 4時,它會返回一個1/4的寬度/高度的圖像。你也可以在android開發者網站上看到更多的細節。

使用這種方法在活動調整

private Bitmap decodeFileWithSmallSize(String sdcard_path) { 
final BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inSampleSize = 4; 
Bitmap myBitmap = BitmapFactory.decodeFile(sdcard_path, options); 
return myBitmap; 
} 

使用

try { 
    Bitmap bitmap = null; 
    if (bitmap != null) { 
     bitmap.recycle(); 
     bitmap = null; 
    } 
    bitmap = decodeFileWithSmallSize("path"); 
} 
catch (OutOfMemoryError e) 
{ 
    Log.e("TAG", 
      "OutOfMemoryError Exception" + e.getMessage()); 
} 
+0

你知道他已經有畢加索的位圖嗎?這個答案如何適用於他的問題?或者對於所有OOME的問題,你是普遍的答案? – Selvin

0

一般同時處理位圖,我們需要通過降低位圖的基礎上我們要求的寬度的採樣大小,以減少內存大小和高度。

這個函數需要位圖文件的路徑,如果你想傳遞位圖改變它與你的要求。但這是適當的方式來有效地加載圖像。

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

欲瞭解更多信息請參考以下鏈接:http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

在你的情況,如果你的目標分鐘級別19,然後用重新配置功能,您可在API級別19 visit developers site

+0

你知道他已經有畢加索的位圖嗎?這個答案如何適用於他的問題?或者對於所有OOME的問題,你是普遍的答案? – Selvin

+0

@Selvin可以請你清楚地看到這個問題,他已經得到了一個位圖(代碼名爲bmp),並在嘗試調整它的大小時,他得到了錯誤。 – Vishwa

+0

@Selvin他沒有任何問題,直到他致電ResizeRichImages函數 – Vishwa